From 5c0d503e954ba4c4f2f225f769de3af0b6e293a3 Mon Sep 17 00:00:00 2001 From: Wanja Zaeske Date: Tue, 15 Jun 2021 12:30:54 +0200 Subject: [PATCH 01/73] update Cargo.lock --- Cargo.lock | 298 ++++++++++++++++++++++++++--------------------------- 1 file changed, 144 insertions(+), 154 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d7d214..24bad0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "698b65a961a9d730fb45b6b0327e20207810c9f61ee421b082b27ba003f49e2b" +checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" dependencies = [ "derive_arbitrary", ] @@ -42,16 +42,16 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", "once_cell", - "vec-arena", + "slab", ] [[package]] @@ -83,29 +83,29 @@ dependencies = [ [[package]] name = "async-io" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" +checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b" dependencies = [ "concurrent-queue", "fastrand", "futures-lite", "libc", "log", - "nb-connect", "once_cell", "parking", "polling", - "vec-arena", + "slab", + "socket2", "waker-fn", "winapi", ] [[package]] name = "async-lock" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" dependencies = [ "event-listener", ] @@ -121,9 +121,9 @@ dependencies = [ [[package]] name = "async-net" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06de475c85affe184648202401d7622afb32f0f74e02192857d0201a16defbe5" +checksum = "69b0a74e7f70af3c8cf1aa539edbd044795706659ac52b78a71dc1a205ecefdf" dependencies = [ "async-io", "blocking", @@ -133,15 +133,16 @@ dependencies = [ [[package]] name = "async-process" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef37b86e2fa961bae5a4d212708ea0154f904ce31d1a4a7f47e1bbc33a0c040b" +checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac" dependencies = [ "async-io", "blocking", "cfg-if", "event-listener", "futures-lite", + "libc", "once_cell", "signal-hook", "winapi", @@ -176,9 +177,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" dependencies = [ "async-stream-impl", "futures-core", @@ -186,9 +187,9 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" dependencies = [ "proc-macro2", "quote", @@ -203,9 +204,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-trait" -version = "0.1.49" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589652ce7ccb335d1e7ecb3be145425702b290dbcb7029bbeaae263fc1d87b48" +checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ "proc-macro2", "quote", @@ -286,18 +287,18 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" dependencies = [ "memchr", ] [[package]] name = "bumpalo" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "byteorder" @@ -328,9 +329,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" [[package]] name = "cfg-if" @@ -363,18 +364,20 @@ dependencies = [ ] [[package]] -name = "cpuid-bool" -version = "0.1.2" +name = "cpufeatures" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +dependencies = [ + "libc", +] [[package]] name = "crossbeam-utils" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", "cfg-if", "lazy_static", ] @@ -439,9 +442,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df89dd0d075dea5cc5fdd6d5df6b8a61172a710b3efac1d6bdb9dd8b78f82c1a" +checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" dependencies = [ "proc-macro2", "quote", @@ -471,9 +474,9 @@ checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" [[package]] name = "fastrand" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" +checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb" dependencies = [ "instant", ] @@ -496,9 +499,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" +checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" dependencies = [ "futures-channel", "futures-core", @@ -511,9 +514,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" +checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" dependencies = [ "futures-core", "futures-sink", @@ -521,15 +524,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" +checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" [[package]] name = "futures-executor" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" +checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" dependencies = [ "futures-core", "futures-task", @@ -538,15 +541,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" +checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" [[package]] name = "futures-lite" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" dependencies = [ "fastrand", "futures-core", @@ -559,10 +562,11 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" +checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" dependencies = [ + "autocfg", "proc-macro-hack", "proc-macro2", "quote", @@ -571,15 +575,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" +checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" [[package]] name = "futures-task" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" +checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" [[package]] name = "futures-timer" @@ -589,10 +593,11 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" +checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" dependencies = [ + "autocfg", "futures-channel", "futures-core", "futures-io", @@ -619,9 +624,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", @@ -658,9 +663,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +checksum = "f0fc1b9fa0e64ffb1aa5b95daa0f0f167734fd528b7c02eabc581d9d843649b1" dependencies = [ "aho-corasick", "bstr", @@ -695,9 +700,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] @@ -724,15 +729,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.3.6" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc35c995b9d93ec174cf9a27d425c7892722101e14993cd227fdb51d70cf9589" +checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" [[package]] name = "idna" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -741,9 +746,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" dependencies = [ "crossbeam-utils", "globset", @@ -820,9 +825,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" +checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" dependencies = [ "wasm-bindgen", ] @@ -844,9 +849,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.93" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "log" @@ -866,19 +871,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "nb-connect" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19900e7eee95eb2b3c2e26d12a874cc80aaf750e31be6fcbe743ead369fa45d" -dependencies = [ - "libc", - "socket2", -] +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "num-traits" @@ -901,9 +896,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opaque-debug" @@ -989,14 +984,14 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "polling" -version = "2.0.3" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc12d774e799ee9ebae13f4076ca003b40d18a11ac0f3641e6f899618580b7b" +checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" dependencies = [ "cfg-if", "libc", "log", - "wepoll-sys", + "wepoll-ffi", "winapi", ] @@ -1020,9 +1015,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] @@ -1050,9 +1045,9 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", @@ -1087,9 +1082,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.5" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", @@ -1098,9 +1093,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.23" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "ringbuffer" @@ -1128,18 +1123,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -1159,13 +1154,13 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f" +checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" dependencies = [ "block-buffer", "cfg-if", - "cpuid-bool", + "cpufeatures", "digest", "opaque-debug", ] @@ -1182,9 +1177,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" dependencies = [ "libc", "signal-hook-registry", @@ -1192,18 +1187,18 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" [[package]] name = "smol" @@ -1241,9 +1236,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.69" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -1261,9 +1256,9 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" dependencies = [ "libc", "winapi", @@ -1290,18 +1285,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" dependencies = [ "proc-macro2", "quote", @@ -1380,9 +1375,9 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] @@ -1401,9 +1396,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "uom" @@ -1418,9 +1413,9 @@ dependencies = [ [[package]] name = "url" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", @@ -1430,25 +1425,20 @@ dependencies = [ [[package]] name = "utf-8" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "value-bag" -version = "1.0.0-alpha.6" +version = "1.0.0-alpha.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b676010e055c99033117c2343b33a40a30b91fecd6c49055ac9cd2d6c305ab1" +checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae" dependencies = [ "ctor", + "version_check", ] -[[package]] -name = "vec-arena" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b2f665b594b07095e3ac3f718e13c2197143416fae4c5706cffb7b1af8d7f1" - [[package]] name = "vec_map" version = "0.8.2" @@ -1486,9 +1476,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" +checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1496,9 +1486,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" +checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" dependencies = [ "bumpalo", "lazy_static", @@ -1511,9 +1501,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea" +checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" dependencies = [ "cfg-if", "js-sys", @@ -1523,9 +1513,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" +checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1533,9 +1523,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" +checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" dependencies = [ "proc-macro2", "quote", @@ -1546,25 +1536,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" +checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" [[package]] name = "web-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" +checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "wepoll-sys" -version = "3.0.1" +name = "wepoll-ffi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" dependencies = [ "cc", ] From 450aa92638ba332561a992953c3dce0cda1adc27 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Mon, 24 May 2021 12:56:52 +0200 Subject: [PATCH 02/73] introduce test failure --- .github/workflows/rust.yml | 1 + src/alerts/mode_1.rs | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e5d10e8..4412fab 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -39,6 +39,7 @@ jobs: - name: Run tests run: cargo test --verbose + clippy_check: runs-on: ubuntu-latest steps: diff --git a/src/alerts/mode_1.rs b/src/alerts/mode_1.rs index 61151bf..f2556b3 100644 --- a/src/alerts/mode_1.rs +++ b/src/alerts/mode_1.rs @@ -33,9 +33,7 @@ impl AlertSystem for Mode1 { let rod = -state.climb_rate.get::(); match state.steep_approach { - true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { - Some(AlertLevel::Warning) - } + true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => None, true if CAUTION_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { Some(AlertLevel::Caution) } From 4d7700768e4950718806af878ec93257e64182ed Mon Sep 17 00:00:00 2001 From: wucke13 Date: Wed, 30 Jun 2021 08:31:58 +0200 Subject: [PATCH 03/73] refine hydrajobs meta --- flake.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 6461e34..a30f83a 100644 --- a/flake.nix +++ b/flake.nix @@ -26,6 +26,9 @@ }; # Hail to the Hydra - hydraJobs = packages; + hydraJobs.opentaws."system" = packages.opentaws // { meta = { + timeout = 86400; + maxSilent = 36000; + };}; }); } From 23394260e1003941a0627c209da81fd7f55936a8 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Thu, 29 Jul 2021 15:21:11 +0200 Subject: [PATCH 04/73] Revert "introduce test failure" This reverts commit 5a80acddd1131aa26f06afb43e6fab33296348a6. --- .github/workflows/rust.yml | 1 - src/alerts/mode_1.rs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4412fab..e5d10e8 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -39,7 +39,6 @@ jobs: - name: Run tests run: cargo test --verbose - clippy_check: runs-on: ubuntu-latest steps: diff --git a/src/alerts/mode_1.rs b/src/alerts/mode_1.rs index f2556b3..61151bf 100644 --- a/src/alerts/mode_1.rs +++ b/src/alerts/mode_1.rs @@ -33,7 +33,9 @@ impl AlertSystem for Mode1 { let rod = -state.climb_rate.get::(); match state.steep_approach { - true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => None, + true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { + Some(AlertLevel::Warning) + } true if CAUTION_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { Some(AlertLevel::Caution) } From 7f5ad681ba9ae11dc8509944e78821f9f5bb180d Mon Sep 17 00:00:00 2001 From: wucke13 Date: Thu, 29 Jul 2021 15:24:27 +0200 Subject: [PATCH 05/73] bump versions --- Cargo.lock | 138 +++++++++++++++---------------- flake.lock | 74 ++++++++++++++--- flake.nix | 62 ++++++++------ src/{alerts/mod.rs => alerts.rs} | 0 4 files changed, 167 insertions(+), 107 deletions(-) rename src/{alerts/mod.rs => alerts.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 24bad0e..150a130 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,12 +83,11 @@ dependencies = [ [[package]] name = "async-io" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" dependencies = [ "concurrent-queue", - "fastrand", "futures-lite", "libc", "log", @@ -121,13 +120,12 @@ dependencies = [ [[package]] name = "async-net" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b0a74e7f70af3c8cf1aa539edbd044795706659ac52b78a71dc1a205ecefdf" +checksum = "5373304df79b9b4395068fb080369ec7178608827306ce4d081cba51cac551df" dependencies = [ "async-io", "blocking", - "fastrand", "futures-lite", ] @@ -204,9 +202,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-trait" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" dependencies = [ "proc-macro2", "quote", @@ -215,9 +213,9 @@ dependencies = [ [[package]] name = "async-tungstenite" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b30ef0ea5c20caaa54baea49514a206308989c68be7ecd86c7f956e4da6378" +checksum = "8645e929ec7964448a901db9da30cd2ae8c7fecf4d6176af427837531dbbb63b" dependencies = [ "async-std", "futures-io", @@ -329,9 +327,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" [[package]] name = "cfg-if" @@ -365,9 +363,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" dependencies = [ "libc", ] @@ -474,9 +472,9 @@ checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" [[package]] name = "fastrand" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb" +checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" dependencies = [ "instant", ] @@ -499,9 +497,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" +checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" dependencies = [ "futures-channel", "futures-core", @@ -514,9 +512,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" +checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" dependencies = [ "futures-core", "futures-sink", @@ -524,15 +522,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" +checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" [[package]] name = "futures-executor" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" +checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" dependencies = [ "futures-core", "futures-task", @@ -541,9 +539,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" +checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" [[package]] name = "futures-lite" @@ -562,9 +560,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" +checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" dependencies = [ "autocfg", "proc-macro-hack", @@ -575,15 +573,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" +checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" [[package]] name = "futures-task" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" +checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" [[package]] name = "futures-timer" @@ -593,9 +591,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" +checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" dependencies = [ "autocfg", "futures-channel", @@ -663,9 +661,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0fc1b9fa0e64ffb1aa5b95daa0f0f167734fd528b7c02eabc581d9d843649b1" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", @@ -709,9 +707,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -779,9 +777,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if", ] @@ -849,9 +847,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.97" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "log" @@ -972,9 +970,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -1015,9 +1013,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -1033,9 +1031,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", @@ -1055,27 +1053,27 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ "rand_core", ] [[package]] name = "rand_pcg" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de198537002b913568a3847e53535ace266f93526caf5c360ec41d72c5787f0" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" dependencies = [ "rand_core", ] @@ -1143,9 +1141,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29" dependencies = [ "itoa", "ryu", @@ -1154,9 +1152,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" +checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" dependencies = [ "block-buffer", "cfg-if", @@ -1220,9 +1218,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" dependencies = [ "libc", "winapi", @@ -1236,9 +1234,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ "proc-macro2", "quote", @@ -1285,18 +1283,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -1314,9 +1312,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" dependencies = [ "tinyvec_macros", ] @@ -1384,9 +1382,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" diff --git a/flake.lock b/flake.lock index 6d27e4b..74a0d60 100644 --- a/flake.lock +++ b/flake.lock @@ -1,15 +1,30 @@ { "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1614513358, + "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "naersk": { "inputs": { "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1618068541, - "narHash": "sha256-enxg0QB53Zis0VJWfJsrX7zCjurpi7lW78EKXbJdzpQ=", + "lastModified": 1623927034, + "narHash": "sha256-sGxlmfp5eXL5sAMNqHSb04Zq6gPl+JeltIZ226OYN0w=", "owner": "nmattia", "repo": "naersk", - "rev": "b3b099d669fc8b18d361c249091c9fe95d57ebbb", + "rev": "e09c320446c5c2516d430803f7b19f5833781337", "type": "github" }, "original": { @@ -20,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1618561750, - "narHash": "sha256-AQIkvh+CQMCZWyKMDP1MalYbk38HWmfeUtjmmH1IFoU=", + "lastModified": 1627561173, + "narHash": "sha256-Y5ihBYW1UpyXVz1T14MTjDlg9gkS480Kz9jSCq3WqbI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "98d6b081d12ebe7e443e62c40ebaeeddbe5bb9fc", + "rev": "4bdce59e5451d8716cfe3e684f4dc181b1b2faff", "type": "github" }, "original": { @@ -34,11 +49,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1618561750, - "narHash": "sha256-AQIkvh+CQMCZWyKMDP1MalYbk38HWmfeUtjmmH1IFoU=", + "lastModified": 1627561173, + "narHash": "sha256-Y5ihBYW1UpyXVz1T14MTjDlg9gkS480Kz9jSCq3WqbI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "98d6b081d12ebe7e443e62c40ebaeeddbe5bb9fc", + "rev": "4bdce59e5451d8716cfe3e684f4dc181b1b2faff", "type": "github" }, "original": { @@ -46,20 +61,55 @@ "type": "indirect" } }, + "nixpkgs_3": { + "locked": { + "lastModified": 1617325113, + "narHash": "sha256-GksR0nvGxfZ79T91UUtWjjccxazv6Yh/MvEJ82v1Xmw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "54c1e44240d8a527a8f4892608c4bce5440c3ecb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { "naersk": "naersk", "nixpkgs": "nixpkgs_2", + "rust-overlay": "rust-overlay", "utils": "utils" } }, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1627524933, + "narHash": "sha256-7qCl4c+vZ+yJhdiOE/yA3rS5wHcuTWIr/opACzrF7tQ=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "b5ee17f42141064953982ece1944ee29b4f88107", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "utils": { "locked": { - "lastModified": 1618217525, - "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=", + "lastModified": 1623875721, + "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", "owner": "numtide", "repo": "flake-utils", - "rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544", + "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index a30f83a..074dab0 100644 --- a/flake.nix +++ b/flake.nix @@ -2,33 +2,45 @@ inputs = { utils.url = "github:numtide/flake-utils"; naersk.url = "github:nmattia/naersk"; + rust-overlay.url = "github:oxalica/rust-overlay"; }; - outputs = { self, nixpkgs, utils, naersk}: - utils.lib.eachSystem [ "aarch64-linux" "i686-linux" "x86_64-linux" ] (system: - let - pkgs = nixpkgs.legacyPackages."${system}"; - naersk-lib = naersk.lib."${system}"; - in rec { - packages.opentaws = naersk-lib.buildPackage { - pname = "opentaws"; - root = ./.; - doCheck = true; - doDoc = true; - copyLibs = true; - doDocFail = true; - copyTarget = true; - }; - defaultPackage = packages.opentaws; + outputs = { self, nixpkgs, utils, naersk, rust-overlay }: + utils.lib.eachSystem [ "aarch64-linux" "i686-linux" "x86_64-linux" ] + (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { inherit system overlays; }; + naersk-lib = naersk.lib."${system}"; + in rec { + packages.opentaws = naersk-lib.buildPackage { + pname = "opentaws"; + root = ./.; + doCheck = true; + doDoc = true; + copyLibs = true; + doDocFail = true; + copyTarget = true; + }; + defaultPackage = packages.opentaws; - devShell = pkgs.mkShell { - nativeBuildInputs = with pkgs; [ rustc cargo ]; - }; + devShell = pkgs.mkShell { + nativeBuildInputs = with pkgs; + [ + (rust-bin.stable.latest.default.override { + extensions = + [ "rust-src" "clippy" "rustfmt" "llvm-tools-preview" ]; + targets = [ "arm-unknown-linux-gnueabihf" ]; + }) + ]; + }; - # Hail to the Hydra - hydraJobs.opentaws."system" = packages.opentaws // { meta = { - timeout = 86400; - maxSilent = 36000; - };}; - }); + # Hail to the Hydra + hydraJobs.opentaws."system" = packages.opentaws // { + meta = { + timeout = 86400; + maxSilent = 36000; + }; + }; + }); } diff --git a/src/alerts/mod.rs b/src/alerts.rs similarity index 100% rename from src/alerts/mod.rs rename to src/alerts.rs From 3a815b7a9df1e23eda6126e8e6d29b6636a66f88 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Thu, 20 May 2021 09:50:57 +0200 Subject: [PATCH 06/73] fix broken no_std build --- Cargo.lock | 9 +++++++++ Cargo.toml | 36 ++++++++++++++++++------------------ src/alerts.rs | 4 +++- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 150a130..cb5a687 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -844,6 +844,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "libc" @@ -1226,6 +1229,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "strsim" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index b488f47..f297916 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,32 +23,32 @@ maintenance = { status = "actively-developed" } [features] default = ["use-serde"] -use-serde = ["serde", "uom/use_serde"] +use-serde = ["uom/use_serde"] [dependencies] casey = "0.3" -lazy_static = "1" -uom = { version = "0", default-features = false, features = [ "f64", "si", "use_serde" ] } +lazy_static = { version = "1", features = [ "spin_no_std" ] } +uom = { version = "0", default-features = false, features = [ "f64", "si" ] } ringbuffer = "0.4" -serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } - -[dev-dependencies] -arbitrary = { version = "1", features = ["derive"] } -cucumber_rust = {version = "0.8", features = [ "macros" ] } -futures = "0" -rand = "*" -rand_pcg = "*" -uom = { version = "*", features = [ "f64", "si", "std", "use_serde" ] } - -# for examples/flightgear -async-tungstenite = { version = "*", features = [ "async-std-runtime" ] } -serde = { version = "^1.0", features = [ "derive" ] } -serde_json = "1.0" -smol = "^1.0" +serde = { version = "1.0", default-features = false, features = [ "derive" ] } +# testing ang examples +arbitrary = { version = "1", features = ["derive"], optional = true } +async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } +cucumber_rust = { version = "0.8", features = [ "macros" ], optional = true } +futures = { version = "0", optional = true } +rand = { version = "*", optional = true } +rand_pcg = { version = "*", optional = true } +serde_json = { version = "1.0", optional = true } +smol = { version = "1.0", optional = true } [[test]] name = "cucumber" harness = false # Allows Cucumber to print output instead of libtest path = "tests/cucumber.rs" +required-features = [ "arbitrary", "cucumber_rust", "futures", "rand", "rand_pcg", "serde_json" ] + +[[example]] +name = "flightgear" +required-features = [ "async-tungstenite", "futures", "serde_json", "smol" ] diff --git a/src/alerts.rs b/src/alerts.rs index 174bf58..9ef8acf 100644 --- a/src/alerts.rs +++ b/src/alerts.rs @@ -185,7 +185,9 @@ impl IntoIterator for &AlertState { type IntoIter = AlertStateIter; fn into_iter(self) -> Self::IntoIter { let mut alerts = self.all_alerts; - alerts.sort_by_key(|option| option.map(|(a, l)| priority(a, l)).unwrap_or(u8::MAX)); + //alerts.sort_by_key(|option| option.map(|(a, l)| priority(a, l)).unwrap_or(u8::MAX)); + // does not work on no_std. + // TODO implement a small sorting algorithm AlertStateIter { sorted_alerts: alerts, From c5d2da5c81e45fb2ce111492e4a172d22d572701 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Fri, 1 Oct 2021 13:47:24 +0200 Subject: [PATCH 07/73] update dependencies --- Cargo.lock | 54 +++++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 4 ++-- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb5a687..c0fb126 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,12 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "array-init" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6945cc5422176fc5e602e590c2878d2c2acd9a4fe20a4baa7c28022521698ec6" + [[package]] name = "async-channel" version = "1.6.1" @@ -392,9 +398,9 @@ dependencies = [ [[package]] name = "cucumber_rust" -version = "0.8.4" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cc67008716666beb00d20d63debed61b55c78f1ccdf4efb629ddae3205d0f52" +checksum = "5d1cc772687e83e581621d37bb11543237dc55618dbc04c8e600928e532dc879" dependencies = [ "async-stream", "async-trait", @@ -406,19 +412,21 @@ dependencies = [ "gherkin_rust", "globwalk", "inventory", + "once_cell", "pathdiff", "regex", "shh", "termcolor", "textwrap 0.12.1", "thiserror", + "tracing", ] [[package]] name = "cucumber_rust_codegen" -version = "0.1.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebf7a94fedf6f251d5cb208ea536496a191c552509a052976af59792199cbc8" +checksum = "4762e59ca6ebc62e043d2ad5ca09e91561520573fd2263df0263320787d3ffc4" dependencies = [ "inflections", "itertools", @@ -1100,11 +1108,11 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "ringbuffer" -version = "0.4.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b101211f7486839baff92d890cffb81b3e8d63ade98d0f434aae27cef1fed10" +checksum = "72dfeba9c94fdc308dcfe165efa6855c698f317484b736605ff859c5fa81d992" dependencies = [ - "generic-array", + "array-init", ] [[package]] @@ -1334,6 +1342,38 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tracing" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" +dependencies = [ + "lazy_static", +] + [[package]] name = "tungstenite" version = "0.13.0" diff --git a/Cargo.toml b/Cargo.toml index f297916..8d79281 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,13 +29,13 @@ use-serde = ["uom/use_serde"] casey = "0.3" lazy_static = { version = "1", features = [ "spin_no_std" ] } uom = { version = "0", default-features = false, features = [ "f64", "si" ] } -ringbuffer = "0.4" +ringbuffer = "0.8" serde = { version = "1.0", default-features = false, features = [ "derive" ] } # testing ang examples arbitrary = { version = "1", features = ["derive"], optional = true } async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } -cucumber_rust = { version = "0.8", features = [ "macros" ], optional = true } +cucumber_rust = { version = "0.9", features = [ "macros" ], optional = true } futures = { version = "0", optional = true } rand = { version = "*", optional = true } rand_pcg = { version = "*", optional = true } From 77aab58902355feb00c4409af9bdf16392f24a77 Mon Sep 17 00:00:00 2001 From: Wanja Zaeske Date: Tue, 2 Nov 2021 09:11:02 +0100 Subject: [PATCH 08/73] major step forward + split openTAWS into multiple crates in a workspace + `aviation_database` contains data of airports + `taws_minimal` is a `no_std` reference implementations of a taws + `kd_tree` implementation of nearest neighbour lookup + `kd_tree_sort` implementation of kd tree generator + `opentaws` core library containing alert functionalities + add aviation_database interface and implementation + add kd_tree implementation for nearest neighbour lookup in aviation database + start implementation of PDA, Mode3 and Five Hundred Foot Altitude Callout + started investigating a new test case generator strategy --- .gitignore | 2 + Cargo.lock | 768 ++++++++++++------ Cargo.toml | 62 +- Makefile | 28 - aviation_database/Cargo.lock | 247 ++++++ aviation_database/Cargo.toml | 25 + aviation_database/README.md | 7 + aviation_database/build.rs | 129 +++ aviation_database/src/consts.rs | 5 + aviation_database/src/lib.rs | 201 +++++ aviation_database/src/reference.rs | 8 + features/ffac.feature | 19 - features/mode_1.feature | 221 ----- kd_tree/Cargo.toml | 12 + kd_tree/src/lib.rs | 267 ++++++ kd_tree_sort/Cargo.toml | 14 + kd_tree_sort/src/lib.rs | 179 ++++ opentaws/Cargo.toml | 34 + {src => opentaws/src}/alerts.rs | 45 +- opentaws/src/alerts/ffac.rs | 42 + {src => opentaws/src}/alerts/flta.rs | 8 +- opentaws/src/alerts/mode_1.rs | 96 +++ {src => opentaws/src}/alerts/mode_2.rs | 6 +- opentaws/src/alerts/mode_3.rs | 73 ++ {src => opentaws/src}/alerts/mode_4.rs | 6 +- {src => opentaws/src}/alerts/mode_5.rs | 6 +- opentaws/src/alerts/pda.rs | 61 ++ {src => opentaws/src}/envelope.rs | 0 opentaws/src/lib.rs | 34 + opentaws/src/macros.rs | 38 + {src => opentaws/src}/prelude.rs | 5 +- {src => opentaws/src}/signal_test.rs | 0 {src => opentaws/src}/terrain_server.rs | 0 {src => opentaws/src}/types.rs | 31 +- src/alerts/ffac.rs | 34 - src/alerts/mode_1.rs | 87 -- src/alerts/mode_3.rs | 22 - src/alerts/pda.rs | 22 - src/lib.rs | 260 ------ src/macros.rs | 65 -- taws_minimal/Cargo.toml | 65 ++ .../examples}/flightgear.rs | 10 +- .../features}/alert_prioritization.feature | 16 +- taws_minimal/features/ffac.feature | 28 + taws_minimal/features/mode_1.feature | 222 +++++ taws_minimal/features/mode_3.feature | 58 ++ taws_minimal/features/pda.feature | 38 + .../features}/self_test.feature | 0 taws_minimal/src/lib.rs | 328 ++++++++ taws_minimal/src/macros.rs | 36 + taws_minimal/tests/cucumber.rs | 300 +++++++ taws_minimal/tests/util/constraint.rs | 320 ++++++++ {tests => taws_minimal/tests}/util/mod.rs | 5 + tests/cucumber.rs | 181 ----- 54 files changed, 3496 insertions(+), 1280 deletions(-) delete mode 100644 Makefile create mode 100644 aviation_database/Cargo.lock create mode 100644 aviation_database/Cargo.toml create mode 100644 aviation_database/README.md create mode 100644 aviation_database/build.rs create mode 100644 aviation_database/src/consts.rs create mode 100644 aviation_database/src/lib.rs create mode 100644 aviation_database/src/reference.rs delete mode 100644 features/ffac.feature delete mode 100644 features/mode_1.feature create mode 100644 kd_tree/Cargo.toml create mode 100644 kd_tree/src/lib.rs create mode 100644 kd_tree_sort/Cargo.toml create mode 100644 kd_tree_sort/src/lib.rs create mode 100644 opentaws/Cargo.toml rename {src => opentaws/src}/alerts.rs (84%) create mode 100644 opentaws/src/alerts/ffac.rs rename {src => opentaws/src}/alerts/flta.rs (51%) create mode 100644 opentaws/src/alerts/mode_1.rs rename {src => opentaws/src}/alerts/mode_2.rs (62%) create mode 100644 opentaws/src/alerts/mode_3.rs rename {src => opentaws/src}/alerts/mode_4.rs (62%) rename {src => opentaws/src}/alerts/mode_5.rs (62%) create mode 100644 opentaws/src/alerts/pda.rs rename {src => opentaws/src}/envelope.rs (100%) create mode 100644 opentaws/src/lib.rs create mode 100644 opentaws/src/macros.rs rename {src => opentaws/src}/prelude.rs (78%) rename {src => opentaws/src}/signal_test.rs (100%) rename {src => opentaws/src}/terrain_server.rs (100%) rename {src => opentaws/src}/types.rs (89%) delete mode 100644 src/alerts/ffac.rs delete mode 100644 src/alerts/mode_1.rs delete mode 100644 src/alerts/mode_3.rs delete mode 100644 src/alerts/pda.rs delete mode 100644 src/lib.rs delete mode 100644 src/macros.rs create mode 100644 taws_minimal/Cargo.toml rename {examples => taws_minimal/examples}/flightgear.rs (90%) rename {features => taws_minimal/features}/alert_prioritization.feature (69%) create mode 100644 taws_minimal/features/ffac.feature create mode 100644 taws_minimal/features/mode_1.feature create mode 100644 taws_minimal/features/mode_3.feature create mode 100644 taws_minimal/features/pda.feature rename {features => taws_minimal/features}/self_test.feature (100%) create mode 100644 taws_minimal/src/lib.rs create mode 100644 taws_minimal/src/macros.rs create mode 100644 taws_minimal/tests/cucumber.rs create mode 100644 taws_minimal/tests/util/constraint.rs rename {tests => taws_minimal/tests}/util/mod.rs (97%) delete mode 100644 tests/cucumber.rs diff --git a/.gitignore b/.gitignore index f0d16fc..11861a1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ target report/ **/result **/result-doc + +aviation_database/airports.json diff --git a/Cargo.lock b/Cargo.lock index c0fb126..f348bbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,11 +20,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyhow" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" + [[package]] name = "arbitrary" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" +checksum = "577b08a4acd7b99869f863c50011b01eb73424ccc798ecd996f2e24817adfca7" dependencies = [ "derive_arbitrary", ] @@ -137,9 +143,9 @@ dependencies = [ [[package]] name = "async-process" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac" +checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" dependencies = [ "async-io", "blocking", @@ -154,9 +160,9 @@ dependencies = [ [[package]] name = "async-std" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341" +checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" dependencies = [ "async-channel", "async-global-executor", @@ -179,27 +185,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "async-stream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "async-task" version = "4.0.3" @@ -219,9 +204,9 @@ dependencies = [ [[package]] name = "async-tungstenite" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8645e929ec7964448a901db9da30cd2ae8c7fecf4d6176af427837531dbbb63b" +checksum = "a0d06e9a20f1c0d64b6067ef6aa9fdf59e194ecde93575591fb4c78063692324" dependencies = [ "async-std", "futures-io", @@ -254,6 +239,25 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "aviation_database" +version = "0.1.0" +dependencies = [ + "anyhow", + "csv", + "kd_tree", + "kd_tree_sort", + "ordered-float", + "proc-macro2", + "quote", + "rayon", + "regex", + "serde", + "serde_json", + "uneval", + "uom", +] + [[package]] name = "base64" version = "0.13.0" @@ -262,9 +266,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" @@ -277,9 +281,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" dependencies = [ "async-channel", "async-task", @@ -291,18 +295,21 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ + "lazy_static", "memchr", + "regex-automata", + "serde", ] [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byteorder" @@ -312,9 +319,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cache-padded" @@ -333,9 +340,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -367,15 +374,64 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "regex", + "terminal_size", + "unicode-width", + "winapi", +] + [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-utils" version = "0.8.5" @@ -386,47 +442,67 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "csv" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + [[package]] name = "ctor" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" dependencies = [ "quote", "syn", ] [[package]] -name = "cucumber_rust" -version = "0.9.0" +name = "cucumber" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1cc772687e83e581621d37bb11543237dc55618dbc04c8e600928e532dc879" +checksum = "eab886787f3c659f408c5fe0a9d7bd1d831ed324fcb55aa89bf339fee8b027b6" dependencies = [ - "async-stream", "async-trait", - "clap", - "cucumber_rust_codegen", - "cute_custom_default", + "atty", + "console", + "cucumber-codegen", + "derive_more", + "either", "futures", - "futures-timer", "gherkin_rust", "globwalk", "inventory", + "itertools", + "linked-hash-map", "once_cell", - "pathdiff", "regex", - "shh", - "termcolor", - "textwrap 0.12.1", - "thiserror", - "tracing", + "sealed", + "structopt", ] [[package]] -name = "cucumber_rust_codegen" -version = "0.9.0" +name = "cucumber-codegen" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4762e59ca6ebc62e043d2ad5ca09e91561520573fd2263df0263320787d3ffc4" +checksum = "9313bba9a820772969ee89f947d91e867c3e37ce6694583ac73466977a9a9f1f" dependencies = [ "inflections", "itertools", @@ -437,20 +513,21 @@ dependencies = [ ] [[package]] -name = "cute_custom_default" -version = "2.1.0" +name = "derive_arbitrary" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed431abf442833fd62ad7cc527a3833d969155c803f0dcf7f8a68db8adddc4c5" +checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" dependencies = [ + "proc-macro2", "quote", "syn", ] [[package]] -name = "derive_arbitrary" -version = "1.0.1" +name = "derive_more" +version = "0.99.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" dependencies = [ "proc-macro2", "quote", @@ -472,6 +549,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "event-listener" version = "2.5.1" @@ -505,9 +588,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" dependencies = [ "futures-channel", "futures-core", @@ -520,9 +603,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" dependencies = [ "futures-core", "futures-sink", @@ -530,15 +613,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" dependencies = [ "futures-core", "futures-task", @@ -547,9 +630,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" [[package]] name = "futures-lite" @@ -568,9 +651,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" dependencies = [ "autocfg", "proc-macro-hack", @@ -581,27 +664,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" dependencies = [ "autocfg", "futures-channel", @@ -724,9 +801,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ "bytes", "fnv", @@ -735,9 +812,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" +checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "idna" @@ -774,29 +851,20 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" -[[package]] -name = "input_buffer" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" -dependencies = [ - "bytes", -] - [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] name = "inventory" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0f7efb804ec95e33db9ad49e4252f049e37e8b0a4652e3cd61f7999f2eff7f" +checksum = "f0eb5160c60ba1e809707918ee329adb99d222888155835c6feedba19f6c3fd4" dependencies = [ "ctor", "ghost", @@ -805,9 +873,9 @@ dependencies = [ [[package]] name = "inventory-impl" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c094e94816723ab936484666968f5b58060492e880f3c8d00489a1e244fa51" +checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548" dependencies = [ "proc-macro2", "quote", @@ -816,28 +884,45 @@ dependencies = [ [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "js-sys" -version = "0.3.51" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kd_tree" +version = "0.1.0" +dependencies = [ + "num", +] + +[[package]] +name = "kd_tree_sort" +version = "0.1.0" +dependencies = [ + "kd_tree", + "rand", + "rand_pcg", + "rayon", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -858,9 +943,24 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.98" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] [[package]] name = "log" @@ -874,15 +974,78 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] [[package]] name = "num-traits" @@ -908,6 +1071,9 @@ name = "once_cell" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +dependencies = [ + "parking_lot", +] [[package]] name = "opaque-debug" @@ -919,21 +1085,23 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "opentaws" version = "0.1.0" dependencies = [ - "arbitrary", - "async-tungstenite", - "casey", - "cucumber_rust", - "futures", + "aviation_database", "lazy_static", - "rand", - "rand_pcg", "ringbuffer", "serde", - "serde_json", - "smol", + "serde_arrays", "uom", ] +[[package]] +name = "ordered-float" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" +dependencies = [ + "num-traits", +] + [[package]] name = "parking" version = "2.0.0" @@ -941,10 +1109,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] -name = "pathdiff" -version = "0.2.0" +name = "parking_lot" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] [[package]] name = "peg" @@ -993,9 +1180,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "polling" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ "cfg-if", "libc", @@ -1006,9 +1193,33 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] [[package]] name = "proc-macro-hack" @@ -1024,18 +1235,18 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -1089,6 +1300,40 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.5.4" @@ -1100,6 +1345,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.25" @@ -1108,9 +1359,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "ringbuffer" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dfeba9c94fdc308dcfe165efa6855c698f317484b736605ff859c5fa81d992" +checksum = "20e49d3a791d79aa7683f8798b274073140865ffb9d65767ace44229d34299e3" dependencies = [ "array-init", ] @@ -1130,20 +1381,47 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sealed" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636b9882a0f4cc2039488df89a10eb4b7976d4b6c1917fc0518f3f0f5e2c72ca" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] +[[package]] +name = "serde_arrays" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -1152,9 +1430,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.65" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29" +checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" dependencies = [ "itoa", "ryu", @@ -1163,9 +1441,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer", "cfg-if", @@ -1174,21 +1452,11 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "shh" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5205eb079ac8be8ec77b7470aff4a050610d42c32819deee362ca414c926d3ab" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "signal-hook" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" +checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" dependencies = [ "libc", "signal-hook-registry", @@ -1205,9 +1473,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "smol" @@ -1229,9 +1503,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", "winapi", @@ -1249,11 +1523,35 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "structopt" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" -version = "1.0.74" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" dependencies = [ "proc-macro2", "quote", @@ -1261,12 +1559,25 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +name = "taws_minimal" +version = "0.1.0" dependencies = [ - "winapi-util", + "arbitrary", + "async-trait", + "async-tungstenite", + "aviation_database", + "casey", + "cucumber", + "futures", + "lazy_static", + "opentaws", + "rand", + "rand_pcg", + "rayon", + "serde", + "serde_json", + "smol", + "uom", ] [[package]] @@ -1294,24 +1605,23 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" dependencies = [ - "terminal_size", "unicode-width", ] [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1329,9 +1639,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -1342,50 +1652,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tracing" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" -dependencies = [ - "lazy_static", -] - [[package]] name = "tungstenite" -version = "0.13.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8dada8c1a3aeca77d6b51a4f1314e0f4b8e438b7b1b71e3ddaca8080e4093" +checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" dependencies = [ "base64", "byteorder", "bytes", "http", "httparse", - "input_buffer", "log", "rand", "sha-1", @@ -1407,19 +1684,26 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] -name = "unicode-bidi" -version = "0.3.5" +name = "uneval" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" +checksum = "df3b95ceb1224b9d137ee19530b0d6f39c66d73098b50d41a4de4ccbf5e4f122" dependencies = [ - "matches", + "serde", + "thiserror", ] +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + [[package]] name = "unicode-normalization" version = "0.1.19" @@ -1437,9 +1721,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -1478,9 +1762,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "value-bag" -version = "1.0.0-alpha.7" +version = "1.0.0-alpha.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae" +checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" dependencies = [ "ctor", "version_check", @@ -1523,9 +1807,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.74" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1533,9 +1817,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.74" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -1548,9 +1832,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.24" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if", "js-sys", @@ -1560,9 +1844,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.74" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1570,9 +1854,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.74" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -1583,15 +1867,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.74" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.51" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 8d79281..c3f5b95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,54 +1,8 @@ -[package] -name = "opentaws" -version = "0.1.0" -authors = [ - "Wanja Zaeske ", - "Janick Beck ", - "Umut Durak ", - ] -edition = "2018" -license = "MIT OR Apache-2.0" -description = "An open source TAWS" -documentation = "https://aeronautical-informatics.github.io/openTAWS/" -readme = "README.md" -repository = "https://github.com/aeronautical-informatics/openTAWS" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[badges] -codecov = { repository = "aeronautical-informatics/openTAWS", branch = "main" } -github = { repository = "aeronautical-informatics/openTAWS" } -is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS" } -maintenance = { status = "actively-developed" } - -[features] -default = ["use-serde"] -use-serde = ["uom/use_serde"] - -[dependencies] -casey = "0.3" -lazy_static = { version = "1", features = [ "spin_no_std" ] } -uom = { version = "0", default-features = false, features = [ "f64", "si" ] } -ringbuffer = "0.8" -serde = { version = "1.0", default-features = false, features = [ "derive" ] } - -# testing ang examples -arbitrary = { version = "1", features = ["derive"], optional = true } -async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } -cucumber_rust = { version = "0.9", features = [ "macros" ], optional = true } -futures = { version = "0", optional = true } -rand = { version = "*", optional = true } -rand_pcg = { version = "*", optional = true } -serde_json = { version = "1.0", optional = true } -smol = { version = "1.0", optional = true } - - -[[test]] -name = "cucumber" -harness = false # Allows Cucumber to print output instead of libtest -path = "tests/cucumber.rs" -required-features = [ "arbitrary", "cucumber_rust", "futures", "rand", "rand_pcg", "serde_json" ] - -[[example]] -name = "flightgear" -required-features = [ "async-tungstenite", "futures", "serde_json", "smol" ] +[workspace] +members = [ + "opentaws", + "taws_minimal", + "aviation_database", + "kd_tree", + "kd_tree_sort" +] diff --git a/Makefile b/Makefile deleted file mode 100644 index 1c599ab..0000000 --- a/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -OCI_ENGINE ?= podman -IMAGE_TAG = alpine-ruby-cucumber -OCI_RUN_CMD = $(OCI_ENGINE) run --tty --interactive $(OCI_LOG_DRIVER) \ - --volume .:/app --workdir /app $(IMAGE_TAG) -OCI_LOG_DRIVER ?= --log-driver=none - -cargo: cargo/test - -cargo/test: - @cargo test - -cargo/build: - @cargo build - -oci/image: - @$(OCI_ENGINE) build --tag $(IMAGE_TAG) contrib/docker-alpine-ruby-cucumber > /dev/null - -report: report/cli - -report/cli: oci/image - @$(OCI_RUN_CMD) - -report/html: oci/image - @mkdir -p report - @$(OCI_RUN_CMD) --format html > report/index.html - -clean: - @rm -rf report target diff --git a/aviation_database/Cargo.lock b/aviation_database/Cargo.lock new file mode 100644 index 0000000..4554032 --- /dev/null +++ b/aviation_database/Cargo.lock @@ -0,0 +1,247 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" + +[[package]] +name = "array-init" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6945cc5422176fc5e602e590c2878d2c2acd9a4fe20a4baa7c28022521698ec6" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "aviation_database" +version = "0.1.0" +dependencies = [ + "anyhow", + "csv", + "opentaws", + "serde", + "uneval", + "uom", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "casey" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14" +dependencies = [ + "syn", +] + +[[package]] +name = "csv" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "opentaws" +version = "0.1.0" +source = "git+https://github.com/aeronautical-informatics/opentaws#d84201785d41fb734e931f143ee0f42c10706a0c" +dependencies = [ + "casey", + "lazy_static", + "ringbuffer", + "serde", + "uom", +] + +[[package]] +name = "proc-macro2" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + +[[package]] +name = "ringbuffer" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e49d3a791d79aa7683f8798b274073140865ffb9d65767ace44229d34299e3" +dependencies = [ + "array-init", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "syn" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "uneval" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b95ceb1224b9d137ee19530b0d6f39c66d73098b50d41a4de4ccbf5e4f122" +dependencies = [ + "serde", + "thiserror", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "uom" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1ee6bfd0a27bf614353809a035cf6880b74239ec6c5e39a7b2860ca16809137" +dependencies = [ + "num-traits", + "serde", + "typenum", +] diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml new file mode 100644 index 0000000..2fae125 --- /dev/null +++ b/aviation_database/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "aviation_database" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +uom = "0.31" +ordered-float = { version = "2.0", default-features = false } +kd_tree = { path = "../kd_tree" } + + +[build-dependencies] +kd_tree_sort = { path = "../kd_tree_sort" } +uom = "0.31" +uneval = "0.2" +serde = {version = "1.0", features = ["derive"]} +serde_json = "1.0" +rayon = "1.5" +quote = "1.0" +proc-macro2 = "1.0" +regex = "1.5" +csv = "1.1" +anyhow = "1.0" diff --git a/aviation_database/README.md b/aviation_database/README.md new file mode 100644 index 0000000..135f08b --- /dev/null +++ b/aviation_database/README.md @@ -0,0 +1,7 @@ +# Todo + +In order for this to work, you need to download the airport database. Download +[this file](https://datahub.io/core/airport-codes/r/airport-codes.json) from +[datahub.io](https://datahub.io/core/airport-codes#data), and store it with the +name `airports.json` root of the `aviation_database` crate (where the +`build.rs` resides). diff --git a/aviation_database/build.rs b/aviation_database/build.rs new file mode 100644 index 0000000..2350695 --- /dev/null +++ b/aviation_database/build.rs @@ -0,0 +1,129 @@ +use proc_macro2::{Literal, TokenStream}; +use quote::{quote, ToTokens}; +use rayon::prelude::*; +use serde::Deserialize; +use std::env; +use std::fs; +use std::path::Path; +use std::process::Command; + +#[derive(Default, Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "snake_case")] +pub struct Airport { + pub continent: String, + pub coordinates: String, + pub elevation_ft: Option, + pub gps_code: Option, + pub iata_code: Option, + pub ident: String, + pub iso_country: String, + pub iso_region: String, + pub local_code: Option, + pub municipality: Option, + pub name: String, + #[serde(rename = "type")] + pub type_field: String, +} + +fn parse_airport_kd(airport: Airport) -> ([f64; 3], Airport) { + let mut coord = airport.coordinates.split(", "); + let lon: f64 = coord.next().map(|l| l.parse().ok()).flatten().unwrap(); + let lat: f64 = coord.next().map(|l| l.parse().ok()).flatten().unwrap(); + let alt: f64 = airport + .elevation_ft + .as_ref() + .map_or_else(|| Some(0.0), |e| e.parse().ok()) + .unwrap(); + + let x = alt * lat.cos() * lon.cos(); + let y = alt * lat.cos() * lon.sin(); + let z = alt * lat.sin(); + ([x, y, z], airport) +} + +impl ToTokens for Airport { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut coord = self.coordinates.split(", "); + let long: Option = coord.next().map(|l| l.parse().ok()).flatten(); + let lat: Option = coord.next().map(|l| l.parse().ok()).flatten(); + let alt: Option = self + .elevation_ft + .as_ref() + .map_or_else(|| Some(0.0), |e| e.parse().ok()); + let icao = format!( + "b\"{}\"", + self.ident + .chars() + .chain(std::iter::repeat('\0')) + .take(4) + .collect::() + ) + .parse::() + .unwrap(); + if long.is_none() || lat.is_none() || alt.is_none() { + return; + } + + tokens.extend(quote! { + AirportEntry { + icao: *#icao, + lat: #lat, + lon: #long, + alt: #alt, + } + }); + } +} + +fn main() { + // Downloaded directly from: + // https://datahub.io/core/airport-codes/r/airport-codes.json + //let airports = File::open("airports.json").unwrap(); + //let mut reader = BufReader::new(airports); + + let read = std::fs::read_to_string("airports.json").unwrap(); + let mut airports: Vec = serde_json::from_str(&read).unwrap(); + let num_airports = airports.len(); + let out_dir = env::var_os("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("airports.rs"); + let airports: Vec<([f64; 3], Airport)> = airports.par_drain(..).map(parse_airport_kd).collect(); + let airports = kd_tree_sort::sort(airports); + let airports: String = airports + .iter() + .fold(String::new(), |mut s, ([x, y, z], a)| { + //s.push_str("e!(#a).to_string()); + // Node + // new(val: [T; DIM], v: V) + s.push_str( + "e! { + Node::new( + [ #x, #y, #z ], + #a + ) + } + .to_string(), + ); + s.push(','); + s + }); + let max_level = (num_airports as f64).log2() as usize + 2; + fs::write( + &dest_path, + format!( + "pub const AIRPORTS: Tree:: = Tree::new([ {} ]);", + num_airports, max_level, airports + ), + ) + .unwrap(); + + // format code + if let Err(e) = Command::new("rustfmt") + .arg(dest_path.as_os_str()) + .current_dir(&out_dir) + .status() + { + eprintln!("{}", e) + } + + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/aviation_database/src/consts.rs b/aviation_database/src/consts.rs new file mode 100644 index 0000000..e14a0bf --- /dev/null +++ b/aviation_database/src/consts.rs @@ -0,0 +1,5 @@ +use crate::AirportEntry; +use kd_tree::{Node, Tree}; + +// Provides const AIRPORTS: &[AirportImpl] = ... +include!(concat!(env!("OUT_DIR"), "/airports.rs")); diff --git a/aviation_database/src/lib.rs b/aviation_database/src/lib.rs new file mode 100644 index 0000000..5d229d1 --- /dev/null +++ b/aviation_database/src/lib.rs @@ -0,0 +1,201 @@ +mod consts; +/// Contains a reference implementation from the +pub mod reference; + +// use opentaws::prelude::*; +use core::{ + fmt::Debug, + iter::{self, Iterator}, +}; +use ordered_float::OrderedFloat; +use uom::{ + num_traits::Pow, + si::{angle::degree, f64::*, length::foot, length::kilometer}, +}; + +use crate::consts::AIRPORTS; + +/// Describes the interface to a TerrainDatabase +/// +/// Each implementation of this type can be use as TerrainDatabase, providing elevation data for a +/// given `Position`. +pub trait TerrainDatabase { + /// Estimate elevation at a specific position + fn elevation_at(&self, position: Position) -> Length; +} + +/// Describes the interface of a AirportDatabase +/// +/// Each implementation of this type can be used as AirportDatabase, providing information about +/// `Airports` and `Runways` +pub trait AirportDatabase: Send + Sync + Debug { + type RunwayIterator: core::iter::Iterator + + From> + + Send + + Sync; + + /// Find the airport nearest to a given `Position` + fn nearest_airport(&self, position: &Position) -> Airport { + // For ~50000 Airports + // Linear Search took 7ms + // KD-Tree Search took 29µs + // CPU: Ryzen 5 5600X + + // Old slow Linear Search + //AIRPORTS.nodes + // .iter() + // .map(|n| Airport::from(n.payload())) + // .map(|a| (a.clone(), a.pos.relative_distance(position))) + // .reduce(|(c_a, c_d), (n_a, n_d)| match c_d.cmp(&n_d) { + // Ordering::Greater => (n_a, n_d), + // _ => (c_a, c_d), + // }) + // .unwrap() + // .0; + + // New fast KD-Tree Search + Airport::from(AIRPORTS.search(&position.cartesian_f64()).payload()) + } + + fn runways(&self, airport: &Airport) -> Self::RunwayIterator { + iter::empty().into() + } + /* + /// Find all Airports in a given perimeter + fn airports_in_perimeter(&self, position: P, perimeter: Length)-> + */ +} + +/// Describes a positon in three dimensional room +#[derive(Debug, Clone, PartialEq)] +pub struct Position { + pub lat: Angle, + pub lon: Angle, + pub alt: Length, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Airport { + pub icao: [u8; 4], + pub pos: Position, +} + +impl Position { + const MEAN_EARTH_RADIUS_KILOMETER: f64 = 6371.001; + /// Converts the `Position` to cartesian coordinates. Nothing orientation is guaranteed, thus + /// this may only be used for relative distances etc. + fn cartesian(&self) -> [Length; 3] { + let x = self.alt * self.lat.cos() * self.lon.cos(); + let y = self.alt * self.lat.cos() * self.lon.sin(); + let z = self.alt * self.lat.sin(); + [x, y, z] + } + + /// Converts the `Position` to cartesian coordinates. Nothing orientation is guaranteed, thus + /// this may only be used for relative distances etc. + fn cartesian_f64(&self) -> [f64; 3] { + let x = self.alt.get::() + * self.lat.get::().cos() + * self.lon.get::().cos(); + let y = self.alt.get::() + * self.lat.get::().cos() + * self.lon.get::().sin(); + let z = self.alt.get::() * self.lat.get::().sin(); + [x, y, z] + } + + /// Get the relative distance of two points + /// + /// This can be used for comparing distances + fn relative_distance(&self, other: &Position) -> RelativeDistance { + RelativeDistance( + self.cartesian() + .iter() + .zip(&other.cartesian()) + .fold(OrderedFloat(0.0), |r, (a, b)| { + r + (a.value - b.value).pow(2) + }), + ) + } + + /// As we have two different altitudes, this function ignores the altitude of `other` and + /// calculates the great circle distance from `self` at the altitude of `self` to lat/lon of + /// `other` + /// + /// This implies, that this operation __is not commutatitve__. E.g. the following code will + /// panic: + /// + /// ``` + /// use crate::reference::PositionImpl; + /// let p1 = PositionImpl::new(54, 10, 0); + /// let p1 = PositionImpl::new(52, 8, 10); + /// + /// assert_eq!(p1.great_circle(p2), p2.great_circle(p1)); + /// ``` + #[allow(non_snake_case)] + pub fn great_circle(&self, other: &Position) -> Length { + // borrows formula from https://en.wikipedia.org/wiki/Great-circle_distance + let λ1 = self.lon; + let λ2 = other.lon; + let Δλ = λ1 - λ2; + let Φ1 = self.lat; + let Φ2 = other.lat; + + let a = Φ2.cos() * Δλ.sin(); + let b = Φ1.cos() * Φ2.sin() - Φ1.sin() * Φ2.cos() * Δλ.cos(); + let c = Φ1.sin() * Φ2.sin() + Φ1.cos() * Φ2.cos() * Δλ.cos(); + + let radius = Length::new::(Self::MEAN_EARTH_RADIUS_KILOMETER) + self.alt; + + radius * ((a * a + b * b) / c).sqrt().atan() + } +} + +/// Distance between two points +#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] +pub struct RelativeDistance(OrderedFloat); + +pub struct AirportEntry { + pub icao: [u8; 4], + pub lat: f64, + pub lon: f64, + pub alt: f64, +} + +impl From<&AirportEntry> for Position { + fn from(entry: &AirportEntry) -> Self { + Self { + lat: Angle::new::(entry.lat), + lon: Angle::new::(entry.lon), + alt: Length::new::(entry.alt), + } + } +} + +impl From<&AirportEntry> for Airport { + fn from(a: &AirportEntry) -> Self { + Airport { + icao: a.icao, + pos: a.into(), + } + } +} + +impl AsRef for Airport { + fn as_ref(&self) -> &Position { + &self.pos + } +} + +impl From for Position { + fn from(entry: AirportEntry) -> Self { + Self { + lat: Angle::new::(entry.lat), + lon: Angle::new::(entry.lon), + alt: Length::new::(entry.alt), + } + } +} + +#[derive(Clone, Debug)] +pub struct Runway(); diff --git a/aviation_database/src/reference.rs b/aviation_database/src/reference.rs new file mode 100644 index 0000000..d518e47 --- /dev/null +++ b/aviation_database/src/reference.rs @@ -0,0 +1,8 @@ +use crate::{AirportDatabase, Runway}; + +#[derive(Debug, Default)] +pub struct AirportDatabaseImpl; + +impl AirportDatabase for AirportDatabaseImpl { + type RunwayIterator = core::iter::Empty; +} diff --git a/features/ffac.feature b/features/ffac.feature deleted file mode 100644 index 3bda85f..0000000 --- a/features/ffac.feature +++ /dev/null @@ -1,19 +0,0 @@ -Feature: Five Hundred Foot Altitude Callout - - @MOPS_292 - Scenario: Five hundred foot above terrain - Given FFAC is armed - And FFAC is not inhibited - And non-precision approach is selected - And the height above terrain is greater or equal to 500 foot - When the height above terrain is lower than 500 foot - Then a FFAC annunciation alert is emitted within 1.3 seconds - - @MOPS_292 - Scenario: Five hundred foot above nearest runway elevation - Given FFAC is armed - And FFAC is not inhibited - And non-precision approach is selected - And the height above nearest runway elevation is greater or equal to 500 foot - When the height above nearest runway elevation is lower than 500 foot - Then a FFAC annunciation alert is emitted within 1.3 seconds \ No newline at end of file diff --git a/features/mode_1.feature b/features/mode_1.feature deleted file mode 100644 index 3db9719..0000000 --- a/features/mode_1.feature +++ /dev/null @@ -1,221 +0,0 @@ -Feature: Mode 1: Excessive Rate of Descent - The Mode 1 alert is intended to generate caution alerts and time-critical - warning alerts when the aircraft has a high rate of descent relative to its - height above terrain. Mode 1 is active during all segments of flight. In - order to reduce nuisance alerts during steep approaches, an optional set of - alerting curves may be employed when the aircraft is performing a steep - approach. The determination if a steep approach is in progress can either be - based on an input to the Equipment (such as a pilot-activated steep approach - switch) or it can be based on internal logic (such as comparison of aircraft - position to approach profiles in a database). - - @MOPS_268 - Scenario: Mode Arming/Disarming - Given the plane is flying - Then Mode 1 shall be armed - - #Rule: Standard Caution Envelope (MOPS_269, MOPS_270) - - @MOPS_269 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is not selected - When the rate of descent is at least feet per minute - And the height above terrain is between 100 and feet - Then a Mode 1 caution alert is emitted within 2 seconds - - Examples: - | rate of descent | height | - | 1560 | 100 | - | 2200 | 630 | - | 5700 | 2200 | - - @MOPS_270 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 caution alert is not emitted at all - - @MOPS_270 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 caution alert is not emitted at all - - @MOPS_270 - Scenario Outline: Must Not Alert - Given steep approach is not selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 caution alert is not emitted at all - - Examples: - | rate of descent | height | - | 964 | 10 | - | 2300 | 1550 | - | 4400 | 2900 | - | 5000 | 3200 | - | 8000 | 4600 | - | 12000 | 6467 | - - #Rule: Steep Approach Caution Envelope (MOPS_271, MOPS_272) - - @MOPS_271 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is selected - When the rate of descent is at least feet per minute - And the height above terrain is between 150 and feet - Then a Mode 1 caution alert is emitted within 2 seconds - - Examples: - | rate of descent | height | - | 1798 | 150 | - | 1944 | 300 | - | 3233 | 1078 | - | 6225 | 2075 | - - @MOPS_272 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 caution alert is not emitted at all - - @MOPS_272 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 caution alert is not emitted at all - - @MOPS_272 - Scenario Outline: Must Not Alert - Given steep approach is selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 caution alert is not emitted at all - - Examples: - | rate of descent | height | - | 964 | 10 | - | 2300 | 1550 | - | 4400 | 2900 | - | 5000 | 3200 | - | 8000 | 4600 | - | 12000 | 6467 | - - #Rule: Warning Envelope (MOPS_273, MOPS_274) - - @MOPS_273 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is not selected - When the rate of descent is at least feet per minute - And the height above terrain is between 100 and feet - Then a Mode 1 warning alert is emitted within 2 seconds - - Examples: - | rate of descent | height | - | 1600 | 100 | - | 1850 | 300 | - | 10100 | 1958 | - - @MOPS_274 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 warning alert is not emitted at all - - @MOPS_274 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 warning alert is not emitted at all - - @MOPS_274 - Scenario Outline: Must Not Alert - Given steep approach is not selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 warning alert is not emitted at all - - Examples: - | rate of descent | height | - | 1217 | 10 | - | 2300 | 1300 | - | 4400 | 2500 | - | 8000 | 3500 | - | 12000 | 4611 | - - #Rule: Steep Approach Warning Envelope (MOPS_275, MOPS_276) - - @MOPS_275 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is selected - When the rate of descent is at least feet per minute - And the height above terrain is between 150 and feet - Then a Mode 1 warning alert is emitted within 2 seconds - - Examples: - | rate of descent | height | - | 1908 | 150 | - | 2050 | 300 | - | 10300 | 1958 | - - @MOPS_276 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 warning alert is not emitted at all - - @MOPS_276 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 warning alert is not emitted at all - - @MOPS_276 - Scenario Outline: Must Not Alert - Given steep approach is selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 warning alert is not emitted at all - - Examples: - | rate of descent | height | - | 1217 | 10 | - | 2300 | 1300 | - | 4400 | 2500 | - | 8000 | 3500 | - | 12000 | 4611 | - - #Rule: Aural Alert (MOPS_277, MOPS_278, MOPS_279, MOPS_280) - - @MOPS_277 - Scenario: Caution Alert - Given a caution level Mode 1 alert arises - Then an aural message "Sink Rate" shall be emitted - - @MOPS_278 - Scenario: Warning Alert - Given a warning level Mode 1 alert arises - Then an aural message "Pull Up" shall be emitted - - @MOPS_279 - Scenario: Repeating Warning Alert - Given the warning level Mode 1 alert condition persists - And the pilot didn't silence the alert - And no higher priority alert is triggered - Then the aural message shall be repeated periodically - - # Whoop-Whoop (MOPS_280) ain't gonna be testable - - #Rule: Visual Alert (MOPS_281, MOPS_282) - - @MOPS_281 - Scenario: Caution - Given a Mode 1 caution alert is active - Then the TAWS shall trigger a yellow or amber indicator - - @MOPS_282 - Scenario: Warning - Given a Mode 1 warning alert is active - Then the TAWS shall trigger a red indicator - -# vim: set ts=2 sw=2 expandtab: retab: expandtab # diff --git a/kd_tree/Cargo.toml b/kd_tree/Cargo.toml new file mode 100644 index 0000000..d5ebf61 --- /dev/null +++ b/kd_tree/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "kd_tree" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[dependencies.num] +version = "0.4" +default-features = false \ No newline at end of file diff --git a/kd_tree/src/lib.rs b/kd_tree/src/lib.rs new file mode 100644 index 0000000..5a861aa --- /dev/null +++ b/kd_tree/src/lib.rs @@ -0,0 +1,267 @@ +#![no_std] +#![allow(clippy::too_many_arguments)] +use core::cmp::Ordering; +use core::fmt::Debug; +use core::ops::{Add, Mul, Sub}; +use num::traits::Zero; + +pub struct Tree { + pub nodes: [Node; SIZE], +} + +impl + Tree +{ + pub const fn new(nodes: [Node; SIZE]) -> Tree { + Tree { nodes } + } +} + +impl< + T: Sized + + PartialOrd + + PartialEq + + Sub + + Add + + Mul + + Zero + + Copy + + Debug + + Default, + V: Sized, + const SIZE: usize, + const DIM: usize, + const MAX_LEVEL: usize, + > Tree +{ + pub fn search(&self, point: &[T; DIM]) -> &Node { + let mut node: &Node = self + .nodes + .first() + .expect("This can not fail, expect if the Tree got no nodes: SIZE == 0"); + let mut index = 0usize; + let mut level = 0usize; + // Store which child nodes where visited for the Node on the index/level and if it was already compared + let mut visited: [(Visited, bool); MAX_LEVEL] = [(Visited::None, false); MAX_LEVEL]; + //Initialise best node/distance with root node + let mut best_distance: T = euclid(&node.val, point); + let mut best_node: &Node = node; + + loop { + // Get to leaf based on comparison of only a single dimension per level + self.search_down(point, &mut node, &mut index, &mut level, &mut visited); + + // Go up until we either reach the top or we go down by one + // Should we go down by one, we will need to go to the best fit leaf of the current subtree + self.search_up( + point, + &mut node, + &mut index, + &mut level, + &mut visited, + &mut best_distance, + &mut best_node, + ); + + // Should we have reached level 0, we are finished + // as search_up should go down by one should we still need to search a subtree + if level == 0 { + break; + } + } + + best_node + } + + fn search_down<'a>( + &'a self, + point: &[T; DIM], + node: &mut &'a Node, + index: &mut usize, + level: &mut usize, + visited: &mut [(Visited, bool); MAX_LEVEL], + ) { + //Get to leaf node + loop { + //Reset Visited and calculated distance for current level + visited[*level] = (Visited::None, false); + + let dim = *level % DIM; + + //If the left node is not reachable we are at a leaf node + if left(index) >= SIZE { + //Set visited for this level to ALL because there are no more child nodes + visited[*level].0 = Visited::All; + return; + } + //Decide where to go + *index = match point[dim].partial_cmp(&node.val[dim]) { + Some(Ordering::Equal) | Some(Ordering::Less) => left(index), + Some(Ordering::Greater) => right(index), + _ => panic!(), + }; + + // If the index is to big we choose the right node + // Make sure it exists, if not go to the left node instead + if *index >= SIZE { + *index -= 1; + } + + // Set next node + *node = self.nodes.get(*index).unwrap(); + + // Increase level for next node + *level += 1; + } + } + + fn search_up<'a>( + &'a self, + point: &[T; DIM], + node: &mut &'a Node, + index: &mut usize, + level: &mut usize, + visited: &mut [(Visited, bool); MAX_LEVEL], + best_distance: &mut T, + best_node: &mut &'a Node, + ) { + loop { + let dim = *level % DIM; + + // Check if current node is a closer node + if !visited[*level].1 { + let candidate: T = euclid(&node.val, point); + if candidate < *best_distance { + *best_distance = candidate; + *best_node = node; + } + visited[*level].1 = true; + } + + // Determine where to go? Up, BottomLeft or BottomRight + let dir: Direction = match visited[*level].0 { + Visited::All => Direction::Up, + Visited::Left => { + // Check if we even can go right + // and if its even possible for the right side to be nearer + let single_distance = point[dim] - node.val[dim]; + let single_distance = single_distance * single_distance; + if right(index) < SIZE && single_distance < *best_distance { + Direction::Right + } else { + Direction::Up + } + } + Visited::Right => { + // Check if we even can go left + // and if its even possible for the left side to be nearer + let single_distance = point[dim] - node.val[dim]; + let single_distance = single_distance * single_distance; + if left(index) < SIZE && single_distance < *best_distance { + Direction::Left + } else { + Direction::Up + } + } + _ => panic!("Unexpected state"), + }; + + match dir { + Direction::Up => { + //Stop if we are at level 0 + if *level == 0 { + return; + } + + // Move up + let parent_index = parent(index); + *level -= 1; + // But update the visited status of the parent first + // This way we know which children were already visited + match visited[*level].0 { + Visited::Left | Visited::Right => visited[*level].0 = Visited::All, + _ => { + if left(&parent_index) == *index { + visited[*level].0 = Visited::Left; + } else { + visited[*level].0 = Visited::Right; + } + } + } + *index = parent_index; + *node = self.nodes.get(*index).unwrap(); + } + Direction::Left => { + *level += 1; + visited[*level].0 = Visited::None; + *index = left(index); + *node = self.nodes.get(*index).unwrap(); + return; + } + Direction::Right => { + *level += 1; + visited[*level].0 = Visited::None; + *index = right(index); + *node = self.nodes.get(*index).unwrap(); + return; + } + } + } + } +} + +#[derive(Copy, Clone, Debug)] +enum Visited { + None, + Left, + Right, + All, +} + +enum Direction { + Up, + Left, + Right, +} + +pub fn parent(cur_index: &usize) -> usize { + (cur_index + 1) / 2 - 1 +} + +pub fn left(cur_index: &usize) -> usize { + (cur_index + 1) * 2 - 1 +} + +pub fn right(cur_index: &usize) -> usize { + (cur_index + 1) * 2 +} + +#[derive(Debug)] +pub struct Node { + val: [T; DIM], + v: V, +} + +impl Node { + pub fn val(&self) -> &[T; DIM] { + &self.val + } + + pub const fn new(val: [T; DIM], v: V) -> Node { + Node { val, v } + } + + pub fn payload(&self) -> &V { + &self.v + } +} + +pub fn euclid(left: &[T; SIZE], right: &[T; SIZE]) -> T +where + T: Default + Add + Sub + Mul + Zero + Copy + Debug, +{ + left.iter() + .zip(right.iter()) + .map(|(x, y)| ((*x) - (*y)) * ((*x) - (*y))) + .fold(T::zero(), ::core::ops::Add::add) +} diff --git a/kd_tree_sort/Cargo.toml b/kd_tree_sort/Cargo.toml new file mode 100644 index 0000000..449c57a --- /dev/null +++ b/kd_tree_sort/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "kd_tree_sort" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +kd_tree = { path = "../kd_tree" } +rayon = "1.5" + +[dev-dependencies] +rand = "0.8" +rand_pcg = "*" diff --git a/kd_tree_sort/src/lib.rs b/kd_tree_sort/src/lib.rs new file mode 100644 index 0000000..44967ff --- /dev/null +++ b/kd_tree_sort/src/lib.rs @@ -0,0 +1,179 @@ +use kd_tree::{left, right}; +use rayon::prelude::*; + +pub fn sort< + T: Sized + PartialOrd + PartialEq + core::fmt::Debug + Send, + V: Sized + Send, + const DIM: usize, +>( + mut values: Vec<([T; DIM], V)>, +) -> Vec<([T; DIM], V)> { + //Add variable for final index + let mut values: Vec<_> = values.par_drain(..).map(|(a, b)| (a, b, 0usize)).collect(); + //Call Recursive Sort function + rec_sort(&mut values, 0, 0); + + //Apply final index by sorting by this index + values.par_sort_by(|(_, _, a), (_, _, b)| { + // Verify inequality of indices + assert_ne!(a, b); + a.cmp(b) + }); + + //Remove index and return + values.par_drain(..).map(|(a, b, _)| (a, b)).collect() +} + +fn rec_sort( + values: &mut [([T; DIM], V, usize)], + dim: usize, + index: usize, +) { + //Check dimension + let dim = dim % DIM; + + // Sort by current dimension + values.par_sort_by(|(a, _, _), (b, _, _)| a[dim].partial_cmp(&b[dim]).unwrap()); + + if values.len() == 1 { + values[0].2 = index; + return; + } else if values.len() == 2 { + values[1].2 = index; + rec_sort(&mut values[..1], dim + 1, left(&index)); + return; + } + let len = values.len(); + let lv = (len as f64).log2() as usize; + let last_line_len = len - 2usize.pow(lv as u32) + 1; + let mid = 2usize.pow(lv as u32) / 2 - 1; + let mid = if last_line_len < 2usize.pow(lv as u32) / 2 { + mid + last_line_len + } else { + mid + 2usize.pow(lv as u32) / 2 + }; + + let (left_slice, rest) = values.split_at_mut(mid); + let (mid, right_slice) = rest.split_at_mut(1); + + mid.get_mut(0).unwrap().2 = index; + // 3 times faster for 50000 elements + [(left_slice, left(&index)), (right_slice, right(&index))] + .into_par_iter() + .for_each(|(s, i)| rec_sort(s, dim + 1, i)); +} + +#[cfg(test)] +mod tests { + #![allow(clippy::float_cmp)] + #![allow(deprecated)] + use crate::sort; + use kd_tree::{euclid, Node, Tree}; + use rand::Rng; + use std::ops::AddAssign; + use std::time::{Duration, Instant}; + type Prng = rand_pcg::Mcg128Xsl64; + + #[test] + fn fixed_test() { + let test = sort(vec![ + ([5, 4], 0), + ([2, 3], 1), + ([8, 1], 2), + ([9, 6], 3), + ([7, 2], 4), + ([4, 7], 5), + ]); + let correct = [ + ([7, 2], 4), + ([5, 4], 0), + ([9, 6], 3), + ([2, 3], 1), + ([4, 7], 5), + ([8, 1], 2), + ]; + + assert_eq!(test, correct) + } + + #[test] + fn search() { + let sorted = sort(vec![ + ([5, 4], 0), + ([2, 3], 1), + ([8, 1], 2), + ([9, 6], 3), + ([7, 2], 4), + ([4, 7], 5), + ]); + + let nodes = sorted + .iter() + .map(|(p, v)| Node::new(*p, *v)) + .collect::>() + .try_into() + .unwrap(); + //T, V, SIZE, DIM, MAX_LEVEL + let tree = Tree::::new(nodes); + + assert_eq!(tree.search(&[5, 3]).val(), &[5, 4]); + assert_eq!(tree.search(&[9, 7]).val(), &[9, 6]); + assert_eq!(tree.search(&[3, 9]).val(), &[4, 7]); + assert_eq!(tree.search(&[3, 0]).val(), &[2, 3]); + } + + #[ignore] + #[test] + fn random_search() { + let mut rng = Prng::new(0xcafef00dd15ea5e5); + let mut duration_linear = Duration::from_secs(0); + let mut duration_tree = Duration::from_secs(0); + + let (iterations, searches) = if cfg!(debug_assertions) { + (10, 50) + } else { + (100, 500) + }; + + #[cfg(debug_assertions)] + const TREE_SIZE: usize = 5000; + #[cfg(not(debug_assertions))] + const TREE_SIZE: usize = 60000; + + #[cfg(debug_assertions)] + const MAX_LEVEL: usize = 13; + #[cfg(not(debug_assertions))] + const MAX_LEVEL: usize = 16; + + for _ in 0..iterations { + let values: Vec<([f64; 3], i32)> = (0..TREE_SIZE) + .map(|_| ([rng.gen(), rng.gen(), rng.gen()], 0)) + .collect(); + let sorted = sort(values.clone()); + let nodes: Vec<_> = sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect(); + let tree: Box> = Box::new(Tree { + nodes: nodes.try_into().unwrap(), + }); + let search_points: Vec<[f64; 3]> = + std::iter::repeat_with(|| [rng.gen(), rng.gen(), rng.gen()]) + .take(searches) + .collect(); + for point in search_points { + let now = Instant::now(); + let closest: f64 = values + .iter() + .map(|a| euclid(&point, &a.0)) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap(); + duration_linear.add_assign(now.elapsed()); + let now = Instant::now(); + let closest_node = tree.search(&point); + duration_tree.add_assign(now.elapsed()); + assert_eq!(closest, euclid(closest_node.val(), &point),); + } + } + + println!("Duration Linear Search: {:?}", duration_linear); + println!("Duration KD Tree Search: {:?}", duration_tree); + } +} diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml new file mode 100644 index 0000000..4d4168f --- /dev/null +++ b/opentaws/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "opentaws" +version = "0.1.0" +authors = [ + "Wanja Zaeske ", + "Janick Beck ", + "Umut Durak ", + ] +edition = "2018" +license = "MIT OR Apache-2.0" +description = "An open source TAWS" +documentation = "https://aeronautical-informatics.github.io/openTAWS/" +readme = "README.md" +repository = "https://github.com/aeronautical-informatics/openTAWS" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[badges] +codecov = { repository = "aeronautical-informatics/openTAWS", branch = "main" } +github = { repository = "aeronautical-informatics/openTAWS" } +is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS" } +maintenance = { status = "actively-developed" } + +[features] +default = ["use-serde"] +use-serde = ["uom/use_serde"] + +[dependencies] +aviation_database = { path = "../aviation_database"} +lazy_static = { version = "1", features = [ "spin_no_std" ] } +uom = { version = "0", default-features = false, features = [ "f64", "si" ] } +ringbuffer = "0.8" +serde = { version = "1.0", default-features = false, features = [ "derive" ] } +serde_arrays = "0.1.0" # Serde const generic "workaround" diff --git a/src/alerts.rs b/opentaws/src/alerts.rs similarity index 84% rename from src/alerts.rs rename to opentaws/src/alerts.rs index 9ef8acf..5051060 100644 --- a/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -78,6 +78,7 @@ impl Eq for AlertLevel {} /// Get the priority of a n (Alert, AlertLevel) tupel /// /// A low value means a high priority. +/// TODO move to every alert file pub fn priority(alert: Alert, alert_level: AlertLevel) -> u8 { use Alert::*; use AlertLevel::*; @@ -99,18 +100,18 @@ pub fn priority(alert: Alert, alert_level: AlertLevel) -> u8 { } } -/// This is the maximum number of different alerts in an alert_state -const ALERT_STATE_SIZE: usize = 8; - /// Collection of a all alerts which are currently present in the TAWS #[derive(Debug, PartialEq)] #[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AlertState { +pub struct AlertState { /// Alerts which are not to be disclosed to the crew to avoid nuisance, but still where triggered - all_alerts: [Option<(Alert, AlertLevel)>; ALERT_STATE_SIZE], + // Workaround until generic arrays are allowed in serde + // https://github.com/serde-rs/serde/issues/1937 + #[serde(with = "serde_arrays")] + all_alerts: [Option<(Alert, AlertLevel)>; N], } -impl AlertState { +impl AlertState { pub fn alerts_total_count(&self) -> usize { self.all_alerts.iter().filter(|e| e.is_some()).count() } @@ -131,7 +132,7 @@ impl AlertState { } /// updates internal alerts with new alerts, removing all old alerts. Prioritizes as well. - pub(crate) fn insert(&mut self, new_alert: Alert, new_alert_level: AlertLevel) { + pub fn insert(&mut self, new_alert: Alert, new_alert_level: AlertLevel) { let mut already_present = false; for (existing_alert, ref mut existing_alert_level) in @@ -156,21 +157,21 @@ impl AlertState { } } -impl Default for AlertState { +impl Default for AlertState { fn default() -> Self { Self { - all_alerts: [None; ALERT_STATE_SIZE], + all_alerts: [None; N], } } } /// An iterator over an `AlertState` -pub struct AlertStateIter { - sorted_alerts: [Option<(Alert, AlertLevel)>; ALERT_STATE_SIZE], +pub struct AlertStateIter { + sorted_alerts: [Option<(Alert, AlertLevel)>; N], index: usize, } -impl Iterator for AlertStateIter { +impl Iterator for AlertStateIter { type Item = (Alert, AlertLevel); fn next(&mut self) -> Option { @@ -180,11 +181,12 @@ impl Iterator for AlertStateIter { } } -impl IntoIterator for &AlertState { +impl IntoIterator for &AlertState { type Item = (Alert, AlertLevel); - type IntoIter = AlertStateIter; + type IntoIter = AlertStateIter; fn into_iter(self) -> Self::IntoIter { let mut alerts = self.all_alerts; + //TODO where do we do prioritisation //alerts.sort_by_key(|option| option.map(|(a, l)| priority(a, l)).unwrap_or(u8::MAX)); // does not work on no_std. // TODO implement a small sorting algorithm @@ -197,9 +199,9 @@ impl IntoIterator for &AlertState { } /// Trait which is to be fulfilled by all functionalities -pub trait AlertSystem: fmt::Debug + Send { +pub trait AlertSystem<'a>: fmt::Debug + Send { /// Allows this system to be instantiated - fn new(config: &TawsConfig) -> Self + fn new(config: &'a TawsConfig<'a>) -> Self where Self: Sized; @@ -225,16 +227,21 @@ pub trait AlertSystem: fmt::Debug + Send { fn is_inhibited(&self) -> bool; /// Process a new AircraftState, emit alerts if appropiate - fn process(&mut self, state: &AircraftState) -> Option; + /// + /// The `u8` refers to the Priority of this AlertFunctionality + fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)>; } #[cfg(test)] mod test { use super::*; + /// This is the maximum number of different alerts in an alert_state + const ALERT_STATE_SIZE: usize = 8; + #[test] pub fn alert_state_propagates_alerts() { - let mut alert_state = AlertState::default(); + let mut alert_state = AlertState::::default(); let test_alerts = [(Alert::Mode3, AlertLevel::Caution)]; for (new_alert, new_alert_level) in &test_alerts { alert_state.insert(*new_alert, *new_alert_level); @@ -245,7 +252,7 @@ mod test { #[test] pub fn alert_state_usage() { - let alts = AlertState::default(); + let alts = AlertState::::default(); // using match for x in &alts { diff --git a/opentaws/src/alerts/ffac.rs b/opentaws/src/alerts/ffac.rs new file mode 100644 index 0000000..9fc2687 --- /dev/null +++ b/opentaws/src/alerts/ffac.rs @@ -0,0 +1,42 @@ +use super::*; +use crate::prelude::*; + +#[derive(Debug)] +pub struct Ffac { + armed: bool, + inhibited: bool, + last_height: Length, +} + +impl<'a> AlertSystem<'a> for Ffac { + fn new(_config: &TawsConfig) -> Self { + Self { + armed: true, + inhibited: false, + last_height: Length::new::(0.0), + } + } + + arm_inhibit!(); + + /// __Notes__: + /// + Per the text in chapter 2.2.1.1.13.2 only "one of the following altitude callouts" must + /// be generated + /// + MOPS_125 speaks of non-precision approaches. However, per Note 3 of chapter + /// 2.2.1.1.13.2, emitation of FFAC "is recommended for all approaches" + fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { + let fivehundred = Length::new::(500.0); + let mut result = None; + + // TODO Do we have to check against nearest runway? + // TODO Is it possible to disarm the FFAC? + + if self.last_height >= fivehundred && state.altitude_ground < fivehundred { + result = Some((AlertLevel::Annunciation, u8::default())); + } + + self.last_height = state.altitude_ground; + + armed_return!(self, result) + } +} diff --git a/src/alerts/flta.rs b/opentaws/src/alerts/flta.rs similarity index 51% rename from src/alerts/flta.rs rename to opentaws/src/alerts/flta.rs index 1fbae1c..c5739e1 100644 --- a/src/alerts/flta.rs +++ b/opentaws/src/alerts/flta.rs @@ -6,8 +6,8 @@ pub struct Flta { inhibited: bool, } -impl AlertSystem for Flta { - fn new(_config: &TawsConfig) -> Self { +impl<'a> AlertSystem<'a> for Flta { + fn new(_config: &'a TawsConfig) -> Self { Self { armed: false, inhibited: false, @@ -16,7 +16,7 @@ impl AlertSystem for Flta { arm_inhibit!(); - fn process(&mut self, _state: &AircraftState) -> Option { - None + fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { + armed_return!(self, None) } } diff --git a/opentaws/src/alerts/mode_1.rs b/opentaws/src/alerts/mode_1.rs new file mode 100644 index 0000000..b4cffe0 --- /dev/null +++ b/opentaws/src/alerts/mode_1.rs @@ -0,0 +1,96 @@ +use uom::si::{length::foot, velocity::foot_per_minute}; + +use crate::envelope::Envelope; +use crate::types::*; + +use super::*; + +#[derive(Clone, Debug)] +pub struct Mode1 { + armed: bool, + inhibited: bool, +} + +impl Default for Mode1 { + fn default() -> Self { + Self { + armed: true, + inhibited: false, + } + } +} + +impl<'a> AlertSystem<'a> for Mode1 { + fn new(_config: &TawsConfig) -> Self { + Self { + armed: true, + inhibited: false, + } + } + + //TODO add real priority + fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { + let altitude = state.altitude_ground.get::(); + let rod = -state.climb_rate.get::(); + + let result = match state.steep_approach { + true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { + Some((AlertLevel::Warning, u8::default())) + } + true if CAUTION_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { + Some((AlertLevel::Caution, u8::default())) + } + false if WARNING_ENVELOPE.contains(rod, altitude) => { + Some((AlertLevel::Warning, u8::default())) + } + false if CAUTION_ENVELOPE.contains(rod, altitude) => { + Some((AlertLevel::Caution, u8::default())) + } + + //self.caution_envelope + _ => None, + }; + + armed_return!(self, result) + } + + arm_inhibit!(); +} + +lazy_static::lazy_static! { + static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new([ + (1200.0, 11.0), + (2550.0, 1550.0), + (4800.0, 2900.0), + (10000.0, 4000.0), + (10001.0, 4000.0), + ]) + .unwrap(); + + static ref CAUTION_ENVELOPE_STEEP_APPROACH: Envelope<5> = Envelope::new([ + (1350.0, 11.0), + (2700.0, 1550.0), + (5300.0, 2900.0), + (10000.0, 4000.0), + (10001.0, 4000.0), + ]) + .unwrap(); + + static ref WARNING_ENVELOPE: Envelope<5> = Envelope::new([ + (1400.0, 11.0), + (2500.0, 1300.0), + (7500.0, 2500.0), + (11000.0, 3000.0), + (11001.0, 3000.0), + ]) + .unwrap(); + + static ref WARNING_ENVELOPE_STEEP_APPROACH: Envelope<5> = Envelope::new([ + (1550.0, 11.0), + (2650.0, 1300.0), + (8000.0, 2500.0), + (11000.0, 3000.0), + (11001.0, 3000.0), + ]) + .unwrap(); +} diff --git a/src/alerts/mode_2.rs b/opentaws/src/alerts/mode_2.rs similarity index 62% rename from src/alerts/mode_2.rs rename to opentaws/src/alerts/mode_2.rs index f229c10..2c0a714 100644 --- a/src/alerts/mode_2.rs +++ b/opentaws/src/alerts/mode_2.rs @@ -6,7 +6,7 @@ pub struct Mode2 { inhibited: bool, } -impl AlertSystem for Mode2 { +impl<'a> AlertSystem<'a> for Mode2 { fn new(_config: &TawsConfig) -> Self { Self { armed: false, @@ -16,7 +16,7 @@ impl AlertSystem for Mode2 { arm_inhibit!(); - fn process(&mut self, _state: &AircraftState) -> Option { - None + fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { + armed_return!(self, None) } } diff --git a/opentaws/src/alerts/mode_3.rs b/opentaws/src/alerts/mode_3.rs new file mode 100644 index 0000000..587104b --- /dev/null +++ b/opentaws/src/alerts/mode_3.rs @@ -0,0 +1,73 @@ +use super::*; +use uom::num::Zero; +use uom::si::f64::Length; + +use crate::envelope::Envelope; +use crate::prelude::*; + +#[derive(Debug)] +pub struct Mode3 { + armed: bool, + inhibited: bool, + max_altitude_ground: Length, +} + +impl<'a> AlertSystem<'a> for Mode3 { + fn new(_config: &TawsConfig) -> Self { + Self { + armed: false, + inhibited: false, + max_altitude_ground: Length::zero(), + } + } + + arm_inhibit!(); + + fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { + let armed = state.go_around || state.take_off; + if let (false, true) = (self.armed, armed) { + self.max_altitude_ground = state.altitude_ground + } + self.armed = armed; + + let mut result = None; + if armed { + if self.max_altitude_ground < state.altitude_ground { + self.max_altitude_ground = state.altitude_ground; + } + let alt_loss = (self.max_altitude_ground - state.altitude_ground).get::(); + let altitude = state.altitude_ground.get::(); + let rod = -state.climb_rate.get::(); + + if CAUTION_ENVELOPE_METHODE_1.contains(rod, altitude) + || CAUTION_ENVELOPE_METHODE_2.contains(alt_loss, altitude) + { + result = Some((AlertLevel::Caution, u8::default())); + } + }; + + armed_return!(self, result) + } +} + +lazy_static::lazy_static! { + /// CAUTION Envelope for Methode 1 + /// X-Axis is Rate of Decent in foot per minute + /// Y-Axis is Height above Terrain in foot + static ref CAUTION_ENVELOPE_METHODE_1: Envelope<3> = Envelope::new([ + (125.0, 50.0), + (480.0, 680.0), + (481.0, 680.0), + ]) + .unwrap(); + + /// CAUTION Envelope for Methode 2 + /// X-Axis is Altitude Loss in foot + /// Y-Axis is Height above Terrain in foot + static ref CAUTION_ENVELOPE_METHODE_2: Envelope<3> = Envelope::new([ + (11.0, 35.0), + (104.0, 1100.0), + (104.0, 1100.0), + ]) + .unwrap(); +} diff --git a/src/alerts/mode_4.rs b/opentaws/src/alerts/mode_4.rs similarity index 62% rename from src/alerts/mode_4.rs rename to opentaws/src/alerts/mode_4.rs index 87236ca..7f7dd1a 100644 --- a/src/alerts/mode_4.rs +++ b/opentaws/src/alerts/mode_4.rs @@ -6,7 +6,7 @@ pub struct Mode4 { inhibited: bool, } -impl AlertSystem for Mode4 { +impl<'a> AlertSystem<'a> for Mode4 { fn new(_config: &TawsConfig) -> Self { Self { armed: false, @@ -16,7 +16,7 @@ impl AlertSystem for Mode4 { arm_inhibit!(); - fn process(&mut self, _state: &AircraftState) -> Option { - None + fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { + armed_return!(self, None) } } diff --git a/src/alerts/mode_5.rs b/opentaws/src/alerts/mode_5.rs similarity index 62% rename from src/alerts/mode_5.rs rename to opentaws/src/alerts/mode_5.rs index 5f6c658..a396a6e 100644 --- a/src/alerts/mode_5.rs +++ b/opentaws/src/alerts/mode_5.rs @@ -6,7 +6,7 @@ pub struct Mode5 { inhibited: bool, } -impl AlertSystem for Mode5 { +impl<'a> AlertSystem<'a> for Mode5 { fn new(_config: &TawsConfig) -> Self { Self { armed: false, @@ -16,7 +16,7 @@ impl AlertSystem for Mode5 { arm_inhibit!(); - fn process(&mut self, _state: &AircraftState) -> Option { - None + fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { + armed_return!(self, None) } } diff --git a/opentaws/src/alerts/pda.rs b/opentaws/src/alerts/pda.rs new file mode 100644 index 0000000..41912b8 --- /dev/null +++ b/opentaws/src/alerts/pda.rs @@ -0,0 +1,61 @@ +use super::*; +use crate::envelope::Envelope; +use crate::prelude::*; +use uom::si::length::nautical_mile; + +#[derive(Debug)] +pub struct Pda<'a> { + armed: bool, + inhibited: bool, + taws_config: &'a TawsConfig<'a>, +} + +impl<'a> AlertSystem<'a> for Pda<'a> { + fn new(config: &'a TawsConfig<'a>) -> Self { + Self { + armed: false, + inhibited: false, + taws_config: config, + } + } + + arm_inhibit!(); + + fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { + let position = state.position(); + let nearest_airport = self.taws_config.terrain_server.nearest_airport(&position); + let distance = position.great_circle(&nearest_airport.pos); + let distance_nm = distance.get::(); + + // MOPS_263 requires PDA to be armed within 5NM of an airport + // But since it may be armed beyond that, we arm/disarm it with a + // distance of 8NM + self.armed = distance_nm <= 8.0; + + // In 2.2.3.1.7.2 some considerations are presented for reducing nuisance alerts + // All of them are satisfied by our CAUTION_ENVELOPE + let result = if self.armed + && CAUTION_ENVELOPE.contains(distance_nm, state.altitude_ground.get::()) + { + Some((AlertLevel::Caution, u8::default())) + } else { + None + }; + + armed_return!(self, result) + } +} + +lazy_static::lazy_static! { + /// CAUTION Envelope for PDA + /// X-Axis is Distance to Airport in nautical miles + /// Y-Axis is Height above Terrain in foot + static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new([ + (0.9, 5.0), + (0.9, 85.0), + (1.8, 155.0), + (2.3, 175.0), + (2.4, 175.0), + ]) + .unwrap(); +} diff --git a/src/envelope.rs b/opentaws/src/envelope.rs similarity index 100% rename from src/envelope.rs rename to opentaws/src/envelope.rs diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs new file mode 100644 index 0000000..cb4f90e --- /dev/null +++ b/opentaws/src/lib.rs @@ -0,0 +1,34 @@ +//! This is a proof of concept TAWS as described in DO-367. It is not even close to fulfilling +//! DO-367 C, the simplest TAWS class. It exists to learn about using BDD (Cucumber & Gherkin in +//! particular) for implementing avionic. +//! +//! # Using openTAWS +//! +//! Currently it is only possible to use openTAWS from Rust. We've looked briefly into WASM-WASI +//! and C ABI as addiotional targets, but this did not lead anywehre usable _so far_. We are very +//! open to suggestions, so please open an issue if you have some feedback. + +#![no_std] +#![deny(unsafe_code)] + +pub use alerts::{functionalities, Alert, AlertLevel, AlertState}; +use prelude::*; +pub use types::*; + +#[macro_use] +pub mod macros; + +mod alerts; +mod envelope; +pub mod prelude; +mod types; + +pub trait Taws { + fn is_armed(&self, alert_system: Alert) -> bool; + fn arm(&mut self, alert_system: Alert); + fn disarm(&mut self, alert_system: Alert); + fn is_inhibited(&self, alert_system: Alert) -> bool; + fn inhibit(&mut self, alert_system: Alert); + fn uninhibit(&mut self, alert_system: Alert); + fn process(&mut self, state: &AircraftState) -> AlertState; +} diff --git a/opentaws/src/macros.rs b/opentaws/src/macros.rs new file mode 100644 index 0000000..d918b95 --- /dev/null +++ b/opentaws/src/macros.rs @@ -0,0 +1,38 @@ +// A helper macro to implement the boring part of all AlertSystems +macro_rules! arm_inhibit { + () => { + fn is_armed(&self) -> bool { + self.armed + } + + fn arm(&mut self) { + self.armed = true; + } + + fn disarm(&mut self) { + self.armed = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + }; +} + +macro_rules! armed_return { + ($self:expr, $result:expr) => { + if $self.is_armed() { + $result + } else { + None + } + }; +} diff --git a/src/prelude.rs b/opentaws/src/prelude.rs similarity index 78% rename from src/prelude.rs rename to opentaws/src/prelude.rs index 04b7131..62a8d45 100644 --- a/src/prelude.rs +++ b/opentaws/src/prelude.rs @@ -4,11 +4,14 @@ //! opentaws::prelude::*`. pub use crate::{ - alerts::{Alert, AlertLevel, AlertState, AlertSystem}, + alerts::{functionalities, Alert, Alert::*, AlertLevel, AlertState, AlertSystem}, types::{AircraftState, TawsConfig}, Taws, }; +#[macro_use] +pub use crate::macros::*; + pub use uom::si::{ acceleration::foot_per_second_squared, angle::degree, diff --git a/src/signal_test.rs b/opentaws/src/signal_test.rs similarity index 100% rename from src/signal_test.rs rename to opentaws/src/signal_test.rs diff --git a/src/terrain_server.rs b/opentaws/src/terrain_server.rs similarity index 100% rename from src/terrain_server.rs rename to opentaws/src/terrain_server.rs diff --git a/src/types.rs b/opentaws/src/types.rs similarity index 89% rename from src/types.rs rename to opentaws/src/types.rs index f7aa7f5..90b9f57 100644 --- a/src/types.rs +++ b/opentaws/src/types.rs @@ -7,7 +7,6 @@ use uom::{ fmt::DisplayStyle::Abbreviation, si::f64::*, si::{ - acceleration::foot_per_second_squared, angle::{degree, revolution}, length::foot, time::second, @@ -15,6 +14,8 @@ use uom::{ }, }; +use aviation_database::{AirportDatabase, Position, Runway}; + /// Represents the current state of an aircraft #[derive(Clone, Debug, Default)] #[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] @@ -62,12 +63,25 @@ pub struct AircraftState { /// Whether steep approach is selected pub steep_approach: bool, + + /// Whether precision approach is selected + pub precision_approach: bool, + + /// Whether go around is selected + pub go_around: bool, + + /// Whether take-off is selected + pub take_off: bool, } /// This configuration holds various details about the aircraft in use. These are necessary for /// example when estimating path trajectories for FLTA. +/// +/// TODO adjust doc string to reflect the existence of terrainserver #[derive(Clone, Debug)] -pub struct TawsConfig { +pub struct TawsConfig<'a> { + pub terrain_server: &'a dyn AirportDatabase>, + pub max_climbrate: Velocity, pub max_climbrate_change: Acceleration, } @@ -108,6 +122,14 @@ impl AircraftState { fn modulo + Rem>(a: T, b: T) -> T { ((a % b) + b) % b } + + pub fn position(&self) -> Position { + Position { + lat: self.position_lat, + lon: self.position_lon, + alt: self.altitude_ground, + } + } } impl fmt::Display for AircraftState { @@ -147,14 +169,17 @@ impl fmt::Display for AircraftState { } } -impl Default for TawsConfig { +/* +impl<'a> Default for TawsConfig<'a> { fn default() -> Self { Self { + terrain_server: &'static AirportDatabaseImpl, max_climbrate: Velocity::new::(700.0), max_climbrate_change: Acceleration::new::(100.0), } } } + */ #[cfg(test)] mod test { diff --git a/src/alerts/ffac.rs b/src/alerts/ffac.rs deleted file mode 100644 index cd99781..0000000 --- a/src/alerts/ffac.rs +++ /dev/null @@ -1,34 +0,0 @@ -use super::*; -use crate::prelude::*; - -#[derive(Debug)] -pub struct Ffac { - armed: bool, - inhibited: bool, - last_height: Length, -} - -impl AlertSystem for Ffac { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: true, - inhibited: false, - last_height: Length::new::(0.0), - } - } - - arm_inhibit!(); - - fn process(&mut self, state: &AircraftState) -> Option { - let fivehundred = Length::new::(500.0); - - if self.last_height >= fivehundred && state.altitude_ground < fivehundred { - return Some(AlertLevel::Annunciation); - } - - // TODO check against runway elevation (MOPS_292) - // - - None - } -} diff --git a/src/alerts/mode_1.rs b/src/alerts/mode_1.rs deleted file mode 100644 index 61151bf..0000000 --- a/src/alerts/mode_1.rs +++ /dev/null @@ -1,87 +0,0 @@ -use uom::si::{length::foot, velocity::foot_per_minute}; - -use crate::envelope::Envelope; -use crate::types::*; - -use super::*; - -#[derive(Clone, Debug)] -pub struct Mode1 { - armed: bool, - inhibited: bool, -} - -impl Default for Mode1 { - fn default() -> Self { - Self { - armed: true, - inhibited: false, - } - } -} - -impl AlertSystem for Mode1 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: true, - inhibited: false, - } - } - - fn process(&mut self, state: &AircraftState) -> Option { - let altitude = state.altitude_ground.get::(); - let rod = -state.climb_rate.get::(); - - match state.steep_approach { - true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { - Some(AlertLevel::Warning) - } - true if CAUTION_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { - Some(AlertLevel::Caution) - } - false if WARNING_ENVELOPE.contains(rod, altitude) => Some(AlertLevel::Warning), - false if CAUTION_ENVELOPE.contains(rod, altitude) => Some(AlertLevel::Caution), - - //self.caution_envelope - _ => None, - } - } - - arm_inhibit!(); -} - -lazy_static::lazy_static! { - -static ref CAUTION_ENVELOPE: Envelope<4> = Envelope::new([ - (1560.0, 100.0), - (2200.0, 630.0), - (5700.0, 2200.0), - (5701.0, 2200.0), - ]) - .unwrap(); - - static ref CAUTION_ENVELOPE_STEEP_APPROACH: Envelope<5> = Envelope::new([ - (1798.0, 150.0), - (1944.0, 300.0), - (3233.0, 1078.0), - (6226.0, 2075.0), - (6227.0, 2075.0), - ]) - .unwrap(); - - static ref WARNING_ENVELOPE: Envelope<4> = Envelope::new([ - (1600.0, 100.0), - (1850.0, 300.0), - (10100.0, 1958.0), - (10101.0, 1958.0), - ]) - .unwrap(); - - static ref WARNING_ENVELOPE_STEEP_APPROACH: Envelope<4> = Envelope::new([ - (1908.0, 150.0), - (2050.0, 300.0), - (10300.0, 1958.0), - (10301.0, 1958.0), - ]) - .unwrap(); -} diff --git a/src/alerts/mode_3.rs b/src/alerts/mode_3.rs deleted file mode 100644 index 122c91d..0000000 --- a/src/alerts/mode_3.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Mode3 { - armed: bool, - inhibited: bool, -} - -impl AlertSystem for Mode3 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option { - None - } -} diff --git a/src/alerts/pda.rs b/src/alerts/pda.rs deleted file mode 100644 index 31d045a..0000000 --- a/src/alerts/pda.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Pda { - armed: bool, - inhibited: bool, -} - -impl AlertSystem for Pda { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option { - None - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 38383d3..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,260 +0,0 @@ -//! This is a proof of concept TAWS as described in DO-367. It is not even close to fulfilling -//! DO-367 C, the simplest TAWS class. It exists to learn about using BDD (Cucumber & Gherkin in -//! particular) for implementing avionic. -//! -//! # Using openTAWS -//! -//! Currently it is only possible to use openTAWS from Rust. We've looked briefly into WASM-WASI -//! and C ABI as addiotional targets, but this did not lead anywehre usable _so far_. We are very -//! open to suggestions, so please open an issue if you have some feedback. - -#![no_std] -#![deny(unsafe_code)] - -pub use alerts::{functionalities, Alert, AlertLevel, AlertState}; -use prelude::*; -pub use types::*; - -#[macro_use] -mod macros; - -mod alerts; -mod envelope; -pub mod prelude; -mod types; - -/// Represents one instance of a TAWS -#[derive(Debug)] -pub struct Taws { - /// `true` if the TAWS is armed - /// - /// There is no specific condition for changing this to `false`. - pub armed: bool, - config: TawsConfig, - ffac: functionalities::Ffac, - flta: functionalities::Flta, - mode1: functionalities::Mode1, - mode2: functionalities::Mode2, - mode3: functionalities::Mode3, - mode4: functionalities::Mode4, - mode5: functionalities::Mode5, - pda: functionalities::Pda, -} - -impl Taws { - functionalities![Ffac, Flta, Mode1, Mode2, Mode3, Mode4, Mode5, Pda]; - - /// Create a new instance of `Taws` - /// - /// # Arguments - /// - /// * `config` - The configuration which this TAWS instance shall use - /// - /// # Example - /// - /// ``` - /// use opentaws::prelude::*; - /// - /// let config = TawsConfig::default(); - /// let taws = Taws::new(config); - /// ``` - pub fn new(config: TawsConfig) -> Self { - use alerts::*; - - let ffac = functionalities::Ffac::new(&config); - let flta = functionalities::Flta::new(&config); - let mode1 = functionalities::Mode1::new(&config); - let mode2 = functionalities::Mode2::new(&config); - let mode3 = functionalities::Mode3::new(&config); - let mode4 = functionalities::Mode4::new(&config); - let mode5 = functionalities::Mode5::new(&config); - let pda = functionalities::Pda::new(&config); - - Self { - armed: true, - config, - ffac, - flta, - mode1, - mode2, - mode3, - mode4, - mode5, - pda, - } - } - - /// Returns `true` if the alert system is armed - /// - /// # Arguments - /// - /// * `alert_system` - The alert system whiches armed state shall be checked - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let taws = Taws::new(config); - /// if taws.is_armed(Alert::Mode1) { - /// // ... - /// } - /// ``` - pub fn is_armed(&self, alert_system: Alert) -> bool { - self.get_functionality(alert_system).is_armed() - } - - /// Arms a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let mut taws = Taws::new(config); - /// taws.arm(Alert::Mode1); - /// - /// assert!(taws.is_armed(Alert::Mode1)); - /// ``` - pub fn arm(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).arm() - } - - /// Disarms a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let mut taws = Taws::new(config); - /// taws.disarm(Alert::Mode1); - /// - /// assert_eq!(taws.is_armed(Alert::Mode1), false); - /// ``` - pub fn disarm(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).disarm() - } - - /// Returns `true` if the alert system is inhibited - /// - /// # Arguments - /// - /// * `alert_system` - The alert system whiches inhibited state shall be checked - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let taws = Taws::new(config); - /// if taws.is_inhibited(Alert::Mode1) { - /// // ... - /// } - /// ``` - pub fn is_inhibited(&self, alert_system: Alert) -> bool { - self.get_functionality(alert_system).is_inhibited() - } - - /// Inhibit a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let mut taws = Taws::new(config); - /// taws.inhibit(Alert::Mode1); - /// - /// assert!(taws.is_inhibited(Alert::Mode1)); - /// ``` - pub fn inhibit(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).inhibit() - } - - /// Uninhibit a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be uninhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let mut taws = Taws::new(config); - /// taws.uninhibit(Alert::Mode1); - /// - /// assert_eq!(taws.is_inhibited(Alert::Mode1), false); - /// ``` - pub fn uninhibit(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).uninhibit() - } - - /// Process a new aircraft state - /// - /// This method must be called regularly for the TAWS to function properly! - /// No warnings will be emitted without calling this function. - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be uninhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # let config = TawsConfig::default(); - /// # let mut taws = Taws::new(config); - /// let aicraft_state = AircraftState::default(); - /// - /// let alert_state = taws.process(&aicraft_state); - /// println!("Received AlertState: {:?}", alert_state); - /// ``` - pub fn process(&mut self, state: &AircraftState) -> AlertState { - let mut alert_state = alerts::AlertState::default(); - - for (alert, alert_system) in self - .functionality_mut_array() - .iter_mut() - .filter(|(_, alert_system)| !alert_system.is_inhibited()) - { - if let Some(alert_level) = alert_system.process(state) { - alert_state.insert(*alert, alert_level); - } - } - - alert_state - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn check_all_alert_systems() { - let taws = Taws::new(Default::default()); - let _ = taws.is_armed(Alert::Ffac); - let _ = taws.is_armed(Alert::Flta); - let _ = taws.is_armed(Alert::Mode1); - let _ = taws.is_armed(Alert::Mode2); - let _ = taws.is_armed(Alert::Mode3); - let _ = taws.is_armed(Alert::Mode4); - let _ = taws.is_armed(Alert::Mode5); - let _ = taws.is_armed(Alert::Pda); - } -} diff --git a/src/macros.rs b/src/macros.rs deleted file mode 100644 index 7ae6826..0000000 --- a/src/macros.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Allow us to iterate over the functionalities for a lack of inline comptime loop unrolling -macro_rules! functionalities { - [$( $functionality_name:tt ),+] => { - /// - fn get_functionality(&self, alert_system: Alert) -> &dyn AlertSystem { - match alert_system { - $( - $crate::alerts::Alert::$functionality_name => casey::lower!(&self.$functionality_name), - )+ - } - } - - fn get_mut_functionality(&mut self, alert_system: Alert) -> &mut dyn AlertSystem { - match alert_system { - $( - $crate::alerts::Alert::$functionality_name => casey::lower!(&mut self.$functionality_name), - )+ - } - } - - fn functionality_mut_array(&mut self)->[(Alert, &mut dyn AlertSystem); count!($($functionality_name)+)]{ - [ $( - ( - $crate::alerts::Alert::$functionality_name, - casey::lower!(&mut self.$functionality_name) as &mut dyn AlertSystem - ), - )+ ] - } - }; -} - -// Count stuff, for a lack of advanced const generics -macro_rules! count { - () => (0usize); - ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); -} - -// A helper macro to implement the boring part of all AlertSystems -macro_rules! arm_inhibit { - () => { - fn is_armed(&self) -> bool { - self.armed - } - - fn arm(&mut self) { - self.armed = true; - } - - fn disarm(&mut self) { - self.armed = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - }; -} diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml new file mode 100644 index 0000000..ce4448f --- /dev/null +++ b/taws_minimal/Cargo.toml @@ -0,0 +1,65 @@ +[package] +name = "taws_minimal" +version = "0.1.0" +authors = [ + "Wanja Zaeske ", + "Janick Beck ", + "Umut Durak ", + ] +edition = "2018" +license = "MIT OR Apache-2.0" +description = "A minimal implementation of openTAWS" +documentation = "https://aeronautical-informatics.github.io/openTAWS/" +readme = "../README.md" +repository = "https://github.com/aeronautical-informatics/openTAWS" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[badges] +codecov = { repository = "aeronautical-informatics/openTAWS", branch = "main" } +github = { repository = "aeronautical-informatics/openTAWS" } +is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS" } +maintenance = { status = "actively-developed" } + +[dependencies] +opentaws = { path = "../opentaws" } +aviation_database = { path = "../aviation_database" } + +uom = { version = "0", default-features = false, features = [ "f64", "si" ] } +casey = "0.3" +serde = { version = "1.0", default-features = false, features = [ "derive" ] } + +# testing ang examples +arbitrary = { version = "1", features = ["derive"], optional = true } +async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } +async-trait = { version = "0.1", optional = true } +cucumber = { version = "0.10", optional = true } +futures = { version = "0", optional = true } +lazy_static = { version = "1.4", optional = true } +rand = { version = "*", optional = true } +rand_pcg = { version = "*", optional = true } +rayon = { version = "1.5", optional = true } +serde_json = { version = "1.0", optional = true } +smol = { version = "1.0", optional = true } + + +[[test]] +name = "cucumber" +harness = false # Allows Cucumber to print output instead of libtest +path = "tests/cucumber.rs" +required-features = [ + "arbitrary", + "async-trait", + "cucumber", + "futures", + "lazy_static", + "rand", + "rand_pcg", + "rayon", + "serde_json", + "smol" +] + +[[example]] +name = "flightgear" +required-features = [ "async-tungstenite", "futures", "serde_json", "smol" ] diff --git a/examples/flightgear.rs b/taws_minimal/examples/flightgear.rs similarity index 90% rename from examples/flightgear.rs rename to taws_minimal/examples/flightgear.rs index 76df24f..3f49d11 100644 --- a/examples/flightgear.rs +++ b/taws_minimal/examples/flightgear.rs @@ -5,10 +5,12 @@ use std::{env, error::Error, time::Instant}; use futures::prelude::*; use async_tungstenite::tungstenite::Message; +use aviation_database::reference::AirportDatabaseImpl; use serde::{Deserialize, Serialize}; use uom::si::velocity::foot_per_second; use opentaws::prelude::*; +use taws_minimal::MinimalTaws; #[derive(Serialize)] struct FlightgearCommand { @@ -68,7 +70,13 @@ fn main() -> Result<(), Box> { let args: Vec = env::args().collect(); let base_uri = args.get(1).expect(USAGE); - let mut taws = Taws::new(Default::default()); + let airport_database = AirportDatabaseImpl::default(); + let config = TawsConfig { + terrain_server: &airport_database, + max_climbrate: Velocity::new::(700.0), + max_climbrate_change: Acceleration::new::(100.0), + }; + let mut taws = MinimalTaws::new(&config); let mut fg_stream = new_flightgear_stream(base_uri.as_str()).await?; let mut frames: u128 = 0; diff --git a/features/alert_prioritization.feature b/taws_minimal/features/alert_prioritization.feature similarity index 69% rename from features/alert_prioritization.feature rename to taws_minimal/features/alert_prioritization.feature index d631ddb..ab73fc9 100644 --- a/features/alert_prioritization.feature +++ b/taws_minimal/features/alert_prioritization.feature @@ -7,12 +7,12 @@ Feature: Alert Priorization caution must alert region. In this case, Class C Equipment needs to only issue the FLTA warning response. - @MOPS_300 - Scenario: Alert Priorization - When concurrent alert conditions trigger - Then the priorization of the alerts handles the concurrency + @MOPS_300 + Scenario: Alert Priorization + When concurrent alert conditions trigger + Then the priorization of the alerts handles the concurrency - @MOPS_300 - Scenario: Alert Priority - Given an alert can occur concurrently - Then that alert has a priority \ No newline at end of file + @MOPS_300 + Scenario: Alert Priority + Given an alert can occur concurrently + Then that alert has a priority \ No newline at end of file diff --git a/taws_minimal/features/ffac.feature b/taws_minimal/features/ffac.feature new file mode 100644 index 0000000..3f0f25d --- /dev/null +++ b/taws_minimal/features/ffac.feature @@ -0,0 +1,28 @@ +Feature: Five Hundred Foot Altitude Callout +Altitude callouts are a category of aural annunciation occurring at a +descending aircraft crossover of a particular height above terrain or height +above runway. The altitude callout is intended to increase flight crew +awareness of the current ground proximity. In particular, the Five Hundred Foot +Callout is required, while other altitude callouts are optional. Besides the +Five Hundred Foot Callout, Class C Equipment may support aural messages for +other specific altitude thresholds. Examples include “four hundred”, “fifty” or +specific approach-related callouts such as “minimums” or “decision height”. +Each of these additional categories of callouts is not required. + + @MOPS_292 + Scenario: Five hundred foot above terrain + Given FFAC is armed + And FFAC is not inhibited + And non-precision approach is selected + And the height above terrain is at least 500 foot + When the height above terrain is at most 500 foot + Then a FFAC annunciation alert is emitted within 1.3 seconds + + @MOPS_292 + Scenario: Five hundred foot above nearest runway elevation + Given FFAC is armed + And FFAC is not inhibited + And non-precision approach is selected + And the nearest runway elevation is at least 500 foot + When the nearest runway elevation is at most 500 foot + Then a FFAC annunciation alert is emitted within 1.3 seconds diff --git a/taws_minimal/features/mode_1.feature b/taws_minimal/features/mode_1.feature new file mode 100644 index 0000000..3899bce --- /dev/null +++ b/taws_minimal/features/mode_1.feature @@ -0,0 +1,222 @@ +#noinspection CucumberUndefinedStep +Feature: Mode 1: Excessive Rate of Descent + The Mode 1 alert is intended to generate caution alerts and time-critical + warning alerts when the aircraft has a high rate of descent relative to its + height above terrain. Mode 1 is active during all segments of flight. In + order to reduce nuisance alerts during steep approaches, an optional set of + alerting curves may be employed when the aircraft is performing a steep + approach. The determination if a steep approach is in progress can either be + based on an input to the Equipment (such as a pilot-activated steep approach + switch) or it can be based on internal logic (such as comparison of aircraft + position to approach profiles in a database). + + @MOPS_268 + Scenario: Mode Arming/Disarming + Given the plane is flying + Then Mode 1 shall be armed + + #Rule: Standard Caution Envelope (MOPS_269, MOPS_270) + + @MOPS_269 + Scenario Outline: Must Alert + Given Mode 1 is armed + And Mode 1 is not inhibited + And steep approach is not selected + When the rate of descent is at least feet per minute + And the height above terrain is between 100 and feet + Then a Mode 1 caution alert is emitted within 2 seconds + + Examples: + | rate_of_descent | height | + | 1560 | 100 | + | 2200 | 630 | + | 5700 | 2200 | + + @MOPS_270 + Scenario: Must Not Alert when not Armed + Given Mode 1 is not armed + Then a Mode 1 caution alert is not emitted at all + + @MOPS_270 + Scenario: Must Not Alert when Inhibited + Given Mode 1 is inhibited + Then a Mode 1 caution alert is not emitted at all + + @MOPS_270 + Scenario Outline: Must Not Alert + Given steep approach is not selected + When the rate of descent is at most feet per minute + But the height above terrain is not between 10 and feet + Then a Mode 1 caution alert is not emitted at all + + Examples: + | rate_of_descent | height | + | 964 | 10 | + | 2300 | 1550 | + | 4400 | 2900 | + | 5000 | 3200 | + | 8000 | 4600 | + | 12000 | 6467 | + + #Rule: Steep Approach Caution Envelope (MOPS_271, MOPS_272) + + @MOPS_271 + Scenario Outline: Must Alert + Given Mode 1 is armed + And Mode 1 is not inhibited + And steep approach is selected + When the rate of descent is at least feet per minute + And the height above terrain is between 150 and feet + Then a Mode 1 caution alert is emitted within 2 seconds + + Examples: + | rate_of_descent | height | + | 1798 | 150 | + | 1944 | 300 | + | 3233 | 1078 | + | 6225 | 2075 | + + @MOPS_272 + Scenario: Must Not Alert when not Armed + Given Mode 1 is not armed + Then a Mode 1 caution alert is not emitted at all + + @MOPS_272 + Scenario: Must Not Alert when Inhibited + Given Mode 1 is inhibited + Then a Mode 1 caution alert is not emitted at all + + @MOPS_272 + Scenario Outline: Must Not Alert + Given steep approach is selected + When the rate of descent is at most feet per minute + But the height above terrain is not between 10 and feet + Then a Mode 1 caution alert is not emitted at all + + Examples: + | rate_of_descent | height | + | 964 | 10 | + | 2300 | 1550 | + | 4400 | 2900 | + | 5000 | 3200 | + | 8000 | 4600 | + | 12000 | 6467 | + + #Rule: Warning Envelope (MOPS_273, MOPS_274) + + @MOPS_273 + Scenario Outline: Must Alert + Given Mode 1 is armed + And Mode 1 is not inhibited + And steep approach is not selected + When the rate of descent is at least feet per minute + And the height above terrain is between 100 and feet + Then a Mode 1 warning alert is emitted within 2 seconds + + Examples: + | rate_of_descent | height | + | 1600 | 100 | + | 1850 | 300 | + | 10100 | 1958 | + + @MOPS_274 + Scenario: Must Not Alert when not Armed + Given Mode 1 is not armed + Then a Mode 1 warning alert is not emitted at all + + @MOPS_274 + Scenario: Must Not Alert when Inhibited + Given Mode 1 is inhibited + Then a Mode 1 warning alert is not emitted at all + + @MOPS_274 + Scenario Outline: Must Not Alert + Given steep approach is not selected + When the rate of descent is at most feet per minute + But the height above terrain is not between 10 and feet + Then a Mode 1 warning alert is not emitted at all + + Examples: + | rate_of_descent | height | + | 1217 | 10 | + | 2300 | 1300 | + | 4400 | 2500 | + | 8000 | 3500 | + | 12000 | 4611 | + + #Rule: Steep Approach Warning Envelope (MOPS_275, MOPS_276) + + @MOPS_275 + Scenario Outline: Must Alert + Given Mode 1 is armed + And Mode 1 is not inhibited + And steep approach is selected + When the rate of descent is at least feet per minute + And the height above terrain is between 150 and feet + Then a Mode 1 warning alert is emitted within 2 seconds + + Examples: + | rate_of_descent | height | + | 1908 | 150 | + | 2050 | 300 | + | 10300 | 1958 | + + @MOPS_276 + Scenario: Must Not Alert when not Armed + Given Mode 1 is not armed + Then a Mode 1 warning alert is not emitted at all + + @MOPS_276 + Scenario: Must Not Alert when Inhibited + Given Mode 1 is inhibited + Then a Mode 1 warning alert is not emitted at all + + @MOPS_276 + Scenario Outline: Must Not Alert + Given steep approach is selected + When the rate of descent is at most feet per minute + But the height above terrain is not between 10 and feet + Then a Mode 1 warning alert is not emitted at all + + Examples: + | rate_of_descent | height | + | 1217 | 10 | + | 2300 | 1300 | + | 4400 | 2500 | + | 8000 | 3500 | + | 12000 | 4611 | + + #Rule: Aural Alert (MOPS_277, MOPS_278, MOPS_279, MOPS_280) + + @MOPS_277 + Scenario: Caution Alert + Given a caution level Mode 1 alert arises + Then an aural message "Sink Rate" shall be emitted + + @MOPS_278 + Scenario: Warning Alert + Given a warning level Mode 1 alert arises + Then an aural message "Pull Up" shall be emitted + + @MOPS_279 + Scenario: Repeating Warning Alert + Given the warning level Mode 1 alert condition persists + And the pilot didn't silence the alert + And no higher priority alert is triggered + Then the aural message shall be repeated periodically + + # Whoop-Whoop (MOPS_280) ain't gonna be testable + + #Rule: Visual Alert (MOPS_281, MOPS_282) + + @MOPS_281 + Scenario: Caution + Given a Mode 1 caution alert is active + Then the TAWS shall trigger a yellow or amber indicator + + @MOPS_282 + Scenario: Warning + Given a Mode 1 warning alert is active + Then the TAWS shall trigger a red indicator + +# vim: set ts=2 sw=2 expandtab: retab: expandtab # diff --git a/taws_minimal/features/mode_3.feature b/taws_minimal/features/mode_3.feature new file mode 100644 index 0000000..4af3c86 --- /dev/null +++ b/taws_minimal/features/mode_3.feature @@ -0,0 +1,58 @@ +#noinspection CucumberUndefinedStep +Feature: Mode 3: Negative Climb Rate or Altitude Loss + The Mode 3 alert is intended to generate caution alerts when the aircraft + loses altitude during take-off or go around. The loss of altitude can either + be based on a negative altitude rate or it can be based on a measured loss of + altitude. + + @MOPS_283 + Scenario: Mode Arming/Disarming + Given take-off is selected + Then Mode 3 shall be armed + + @MOPS_283 + Scenario: Mode Arming/Disarming + Given go around is selected + Then Mode 3 shall be armed + + @MOPS_284 + Scenario: Mode Arming/Disarming + Given take-off is not selected + And go around is not selected + Then Mode 3 shall not be armed + + # MOPS_285: either alerting on Mode 1 or Mode 2 is sufficient, if both are + # used again only one is sufficient + + #Rule: Method 1 + @MOPS_286 + Scenario Outline: Must Alert + Given Mode 3 is armed + And Mode 3 is not inhibited + When the rate of descent is at least feet per minute + And the height above terrain is between 100 and feet + Then a Mode 3 caution alert is emitted within 1.3 seconds + + Examples: + | rate_of_descent | height | + | 207 | 60 | + | 533 | 600 | + | 534 | 600 | + + @MOPS_287 + Scenario: Must Not Alert when not Armed + Given Mode 3 is not armed + Then a Mode 3 caution alert is not emitted at all + + @MOPS_287 + Scenario: Must Not Alert when Inhibited + Given Mode 3 is inhibited + Then a Mode 3 caution alert is not emitted at all + + @MOPS_287 + Scenario Outline: Must Not Alert + When the rate of descent is at most feet per minute + But the height above terrain is not between 10 and feet + Then a Mode 3 caution alert is not emitted at all + + diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature new file mode 100644 index 0000000..2cebcaa --- /dev/null +++ b/taws_minimal/features/pda.feature @@ -0,0 +1,38 @@ +#noinspection CucumberUndefinedStep +Feature: PDA: Premature Decent Alerting + # TODO: Description + + @MOPS_263 + Scenario: Mode Arming/Disarming + Given the plane is within 5 NM of an airport + Then PDA shall be armed + + # TODO Add Criteria for PDA to be disarmed beyond 5 NM due to the risk of nuisance alerts (2.2.3.1.7.2) + + @MOPS_264 + Scenario Outline: Must Alert + Given PDA is armed + And PDA is not inhibited + When the distance to the nearest airport is between 1.0 and NM + And the height above terrain is between 10 and feet + Then a PDA caution alert is emitted within 1.3 seconds + + Examples: + | distance_to_airport | height | + | 1.0 | 80 | + | 1.8 | 150 | + | 2.3 | 170 | + + @MOPS_265 + Scenario: Must Not Alert when not Armed + Given PDA is not armed + Then a PDA caution alert is not emitted at all + + @MOPS_265 + Scenario: Must Not Alert when Inhibited + Given PDA is inhibited + Then a PDA caution alert is not emitted at all + + # MOPS_266 and MOPS_267 are not testable + +# vim: set ts=2 sw=2 expandtab: retab: expandtab # diff --git a/features/self_test.feature b/taws_minimal/features/self_test.feature similarity index 100% rename from features/self_test.feature rename to taws_minimal/features/self_test.feature diff --git a/taws_minimal/src/lib.rs b/taws_minimal/src/lib.rs new file mode 100644 index 0000000..116fe42 --- /dev/null +++ b/taws_minimal/src/lib.rs @@ -0,0 +1,328 @@ +use opentaws::prelude::*; + +#[macro_use] +mod macros; + +/// This is the number of different alerts in an alert_state for MinimalTAWS +const ALERT_STATE_SIZE: usize = 8; + +/// Represents one instance of a TAWS +#[derive(Debug)] +pub struct MinimalTaws<'a> { + /// `true` if the TAWS is armed + /// + /// There is no specific condition for changing this to `false`. + pub armed: bool, + config: &'a TawsConfig<'a>, + ffac: functionalities::Ffac, + flta: functionalities::Flta, + mode1: functionalities::Mode1, + mode2: functionalities::Mode2, + mode3: functionalities::Mode3, + mode4: functionalities::Mode4, + mode5: functionalities::Mode5, + pda: functionalities::Pda<'a>, +} + +impl<'a> MinimalTaws<'a> { + functionalities![Ffac, Flta, Mode1, Mode2, Mode3, Mode4, Mode5, Pda]; + + /// Create a new instance of `Taws` + /// + /// # Arguments + /// + /// * `config` - The configuration which this TAWS instance shall use + /// + /// # Example + /// + /// ``` + /// use opentaws::prelude::*; + /// use taws_minimal::MinimalTaws; + /// + /// let config = TawsConfig::default(); + /// let taws = MinimalTaws::new(&config); + /// ``` + pub fn new(config: &'a TawsConfig) -> Self { + let ffac = functionalities::Ffac::new(config); + let flta = functionalities::Flta::new(config); + let mode1 = functionalities::Mode1::new(config); + let mode2 = functionalities::Mode2::new(config); + let mode3 = functionalities::Mode3::new(config); + let mode4 = functionalities::Mode4::new(config); + let mode5 = functionalities::Mode5::new(config); + let pda = functionalities::Pda::new(config); + + Self { + armed: true, + config, + ffac, + flta, + mode1, + mode2, + mode3, + mode4, + mode5, + pda, + } + } +} + +impl<'a> Taws for MinimalTaws<'a> { + /// Returns `true` if the alert system is armed + /// + /// # Arguments + /// + /// * `alert_system` - The alert system whiches armed state shall be checked + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let taws = MinimalTaws::new(&config); + /// if taws.is_armed(Alert::Mode1) { + /// // ... + /// } + /// ``` + fn is_armed(&self, alert_system: Alert) -> bool { + self.get_functionality(alert_system).is_armed() + } + + /// Arms a specific alert system + /// + /// # Arguments + /// + /// * `alert_system` - The alert system which shall be inhibited + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let mut taws = MinimalTaws::new(&config); + /// taws.arm(Alert::Mode1); + /// + /// assert!(taws.is_armed(Alert::Mode1)); + /// ``` + fn arm(&mut self, alert_system: Alert) { + self.get_mut_functionality(alert_system).arm(); + } + + /// Disarms a specific alert system + /// + /// # Arguments + /// + /// * `alert_system` - The alert system which shall be inhibited + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let mut taws = MinimalTaws::new(&config); + /// taws.disarm(Alert::Mode1); + /// + /// assert_eq!(taws.is_armed(Alert::Mode1), false); + /// ``` + fn disarm(&mut self, alert_system: Alert) { + self.get_mut_functionality(alert_system).disarm() + } + + /// Returns `true` if the alert system is inhibited + /// + /// # Arguments + /// + /// * `alert_system` - The alert system whiches inhibited state shall be checked + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let taws = MinimalTaws::new(&config); + /// if taws.is_inhibited(Alert::Mode1) { + /// // ... + /// } + /// ``` + fn is_inhibited(&self, alert_system: Alert) -> bool { + self.get_functionality(alert_system).is_inhibited() + } + + /// Inhibit a specific alert system + /// + /// # Arguments + /// + /// * `alert_system` - The alert system which shall be inhibited + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let mut taws = MinimalTaws::new(&config); + /// taws.inhibit(Alert::Mode1); + /// + /// assert!(taws.is_inhibited(Alert::Mode1)); + /// ``` + fn inhibit(&mut self, alert_system: Alert) { + self.get_mut_functionality(alert_system).inhibit() + } + + /// Uninhibit a specific alert system + /// + /// # Arguments + /// + /// * `alert_system` - The alert system which shall be uninhibited + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let mut taws = MinimalTaws::new(&config); + /// taws.uninhibit(Alert::Mode1); + /// + /// assert_eq!(taws.is_inhibited(Alert::Mode1), false); + /// ``` + fn uninhibit(&mut self, alert_system: Alert) { + self.get_mut_functionality(alert_system).uninhibit() + } + + /// Process a new aircraft state + /// + /// This method must be called regularly for the TAWS to function properly! + /// No warnings will be emitted without calling this function. + /// + /// # Arguments + /// + /// * `alert_system` - The alert system which shall be uninhibited + /// + /// # Example + /// + /// ``` + /// # use opentaws::prelude::*; + /// # use taws_minimal::MinimalTaws; + /// # let config = TawsConfig::default(); + /// # let mut taws = MinimalTaws::new(&config); + /// let aicraft_state = AircraftState::default(); + /// + /// let alert_state = taws.process(&aicraft_state); + /// println!("Received AlertState: {:?}", alert_state); + /// ``` + fn process(&mut self, state: &AircraftState) -> AlertState { + let mut alert_state = AlertState::default(); + + for (alert, alert_system) in self + .functionality_mut_array() + .iter_mut() + .filter(|(_, alert_system)| !alert_system.is_inhibited()) + { + if let Some((alert_level, _priority)) = alert_system.process(state) { + alert_state.insert(*alert, alert_level); + } + } + + alert_state + } +} + +#[cfg(test)] +mod test { + use super::*; + use aviation_database::reference::AirportDatabaseImpl; + + #[test] + fn check_all_alert_systems() { + let airport_database = AirportDatabaseImpl::default(); + let config = TawsConfig { + terrain_server: &airport_database, + max_climbrate: Velocity::new::(700.0), + max_climbrate_change: Acceleration::new::(100.0), + }; + let taws = MinimalTaws::new(&config); + let _ = taws.is_armed(Alert::Ffac); + let _ = taws.is_armed(Alert::Flta); + let _ = taws.is_armed(Alert::Mode1); + let _ = taws.is_armed(Alert::Mode2); + let _ = taws.is_armed(Alert::Mode3); + let _ = taws.is_armed(Alert::Mode4); + let _ = taws.is_armed(Alert::Mode5); + let _ = taws.is_armed(Alert::Pda); + } + + #[test] + fn check_edge_case_1() { + use uom::si::{ + angle::{degree, revolution}, + length::meter, + time::second, + velocity::meter_per_second, + }; + + let airport_database = AirportDatabaseImpl::default(); + let config = TawsConfig { + terrain_server: &airport_database, + max_climbrate: Velocity::new::(700.0), + max_climbrate_change: Acceleration::new::(100.0), + }; + let mut taws = MinimalTaws::new(&config); + //Angle::new::(1.0) + + let input = AircraftState { + timestamp: Time::new::(-1192551353.0), + altitude: Length::new::(4608227.6136), + altitude_ground: Length::new::(45.72), + climb_rate: Velocity::new::(-3533302.6819200004), + position_lat: Angle::new::(-24748089.039895818), + position_lon: Angle::new::(-19226236.894961454), + speed_ground: Velocity::new::(1060688081.2833334), + speed_air: Velocity::new::(-87219196.62777779), + heading: Angle::new::(-31215539.612156395), + pitch: Angle::new::(-15680644.065499812), + roll: Angle::new::(10762607.494661978), + steep_approach: true, + precision_approach: false, + go_around: false, + take_off: false, + }; + let output = taws.process(&input); + + assert_eq!( + output.priority_alert(), + Some((Alert::Mode1, AlertLevel::Warning)) + ); + } + // ———— [!] Step failed: ——————————————————————————  p_tester/src/tester.rs:220:25 + // Aicraft state that violated the scenario: AircraftState { + // timestamp: -1192551353.0 s^1, + // altitude: 4608227.6136 m^1, + // altitude_ground: 45.72 m^1, + // climb_rate: -3533302.6819200004 m^1 s^-1, + // position_lat: -24748089.039895818, + // position_lon: -19226236.894961454, + // speed_ground: 1060688081.2833334 m^1 s^-1, + // speed_air: -87219196.62777779 m^1 s^-1, + // heading: -31215539.612156395, + // pitch: -15680644.065499812, + // roll: 10762607.494661978, + // steep_approach: true, + // } + // alerts emitted: AlertState { + // all_alerts: [ + // None, + // None, + // None, + // None, + // None, + // None, + // None, + // None, + // ], + // } +} diff --git a/taws_minimal/src/macros.rs b/taws_minimal/src/macros.rs new file mode 100644 index 0000000..5b5e39a --- /dev/null +++ b/taws_minimal/src/macros.rs @@ -0,0 +1,36 @@ +// Allow us to iterate over the functionalities for a lack of inline comptime loop unrolling +macro_rules! functionalities { + [$( $functionality_name:tt ),+] => { + /// + fn get_functionality(&self, alert_system: Alert) -> &dyn AlertSystem<'a> { + match alert_system { + $( + $functionality_name => casey::lower!(&self.$functionality_name), + )+ + } + } + + fn get_mut_functionality(&mut self, alert_system: Alert) -> &mut dyn AlertSystem<'a> { + match alert_system { + $( + $functionality_name => casey::lower!(&mut self.$functionality_name), + )+ + } + } + + fn functionality_mut_array(&mut self)->[(Alert, &mut dyn AlertSystem<'a>); count!($($functionality_name)+)]{ + [ $( + ( + $functionality_name, + casey::lower!(&mut self.$functionality_name) as &mut dyn AlertSystem + ), + )+ ] + } + }; +} + +// Count stuff, for a lack of advanced const generics +macro_rules! count { + () => (0usize); + ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); +} diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs new file mode 100644 index 0000000..d917c33 --- /dev/null +++ b/taws_minimal/tests/cucumber.rs @@ -0,0 +1,300 @@ +use std::cmp::PartialEq; +use std::convert::Infallible; + +use uom::si::{f64::*, length::foot, velocity::foot_per_minute}; + +use async_trait::async_trait; +use cucumber::{given, then, when, WorldInit}; +use opentaws::prelude::*; +use taws_minimal::MinimalTaws; + +mod util; +use util::*; + +use util::constraint::*; + +fn main() { + smol::block_on(MyWorld::run("features")); +} + +// TODO check for parallel testing +// TODO allow for statefull tests +// TODO evaluate merge possibilities re parser functions for similar sentences + +#[derive(WorldInit)] +pub struct MyWorld { + taws: MinimalTaws<'static>, + constraints: Vec, + test_length: usize, + last_step_type: StepType, + phase: usize, +} + +//TODO use cucumber rs StepType enum +#[derive(PartialEq)] +pub enum StepType { + Given, + When, + Then, +} + +#[given("the plane is flying")] +fn is_flying(_world: &mut MyWorld) {} + +#[given(regex = r#"^(.+) is ?(not)? armed$"#)] +fn is_armed(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { + if maybe_not == "not" { + world.taws.disarm(alert.into()); + } else { + world.taws.arm(alert.into()); + } +} + +#[given(regex = "^(.+) is ?(not)? inhibited$")] +fn is_inhibited(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { + if maybe_not == "not" { + world.taws.uninhibit(alert.into()); + } else { + world.taws.inhibit(alert.into()); + } +} + +#[given(regex = r"^steep approach is ?(not)? selected$")] +fn steep_approach(world: &mut MyWorld, maybe_not: String) { + world.update_phase(StepType::Given); + if maybe_not == "not" { + world.constraints[world.phase].add_steep_approach_constraint(false) + } else { + world.constraints[world.phase].add_steep_approach_constraint(true) + } +} + +#[given(regex = r"^take-off is ?(not)? selected$")] +fn take_of(world: &mut MyWorld, maybe_not: String) { + world.update_phase(StepType::Given); + if maybe_not == "not" { + world.constraints[world.phase].add_take_off_constraint(false) + } else { + world.constraints[world.phase].add_take_off_constraint(true) + } +} + +#[given(regex = r"^go around is ?(not)? selected$")] +fn go_around(world: &mut MyWorld, maybe_not: String) { + world.update_phase(StepType::Given); + if maybe_not == "not" { + world.constraints[world.phase].add_go_around_constraint(false) + } else { + world.constraints[world.phase].add_go_around_constraint(true) + } +} + +#[given(regex = r"^non-precision approach is ?(not)? selected$")] +fn precision_approach(world: &mut MyWorld, maybe_not: String) { + world.update_phase(StepType::Given); + + // double negation: non-precision is not selected + if maybe_not == "not" { + world.constraints[world.phase].add_precision_approach_constraint(true); + } else { + world.constraints[world.phase].add_precision_approach_constraint(false); + } +} + +#[then(regex = r"^(.+) shall ?(not)? be armed$")] +fn shall_be_armed(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { + assert_eq!(world.taws.is_armed(alert.into()), !maybe_not.eq("not")); +} + +#[when(regex = r"^the rate of descent is at (most|least) (\d+) feet per minute$")] +fn rate_of_descent(world: &mut MyWorld, most_or_least: String, rod: f64) { + world.update_phase(StepType::When); + + let rod = Velocity::new::(rod); + // most and least are swapped here, as aircraft_state stores rate of climb, while + // the sentence give rate of descent + // TODO validate that this is a safe assumption? + match most_or_least.as_str() { + "most" => { + world.constraints[world.phase] + .add_climb_rate_constraint(Constraint::AtLeast(world.phase, -rod)); + //world.add_mould(move |a| bouncer.at_least(&mut a.climb_rate, -rod)); + } + "least" => { + world.constraints[world.phase] + .add_climb_rate_constraint(Constraint::AtMost(world.phase, -rod)); + //world.add_mould(move |a| bouncer.at_most(&mut a.climb_rate, -rod)); + } + _ => { + panic!("unable to parse this sentence"); + } + } +} + +#[when(regex = r"^the height above terrain is ?(not)? between (\d+) and (\d+) feet$")] +fn height_above_terrain(world: &mut MyWorld, maybe_not: String, lower: f64, upper: f64) { + world.update_phase(StepType::When); + + let height_at_least = Length::new::(lower); + let height_at_most = Length::new::(upper); + + if maybe_not == "not" { + world.constraints[world.phase].add_altitude_ground_constraint(Constraint::NotInRange( + world.phase, + height_at_least, + height_at_most, + )); + } else { + world.constraints[world.phase].add_altitude_ground_constraint(Constraint::InRange( + world.phase, + height_at_least, + height_at_most, + )); + // TODO altitude or altitude_ground + } +} + +#[when( + regex = r"^the distance to the nearest airport is ?(not)? between ([0-9]+\.?[0-9]*) and ([0-9]+\.?[0-9]*) NM" +)] +fn distance_to_airport(world: &mut MyWorld, maybe_not: String, lower: f64, upper: f64) { + world.update_phase(StepType::When); + todo!(); + let height_at_least = Length::new::(lower); + let height_at_most = Length::new::(upper); + + if maybe_not == "not" { + } else { + } +} + +#[given(regex = r"^the height above terrain is at (most|least) (\d+) foot$")] +fn height_above_terrain_2(world: &mut MyWorld, greater_or_less: String, height: f64) { + todo!("Merge with previous function"); +} + +#[given(regex = r"^the nearest runway elevation is at (most|least) (\d+) foot$")] +fn height_above_runway(world: &mut MyWorld, greater_or_less: String, height: f64) { + todo!("Merge with previous function"); +} + +#[given(regex = r"^the plane is ?(not)? within ([0-9]+\.?[0-9]*) NM of an airport")] +fn distance_to_airport_2(world: &mut MyWorld, maybe_not: String, distance: f64) { + todo!("Merge with previous function"); +} + +#[then(regex = "^a (.*) alert is not emitted at all$")] +fn is_not_emitted(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper) { + world.update_phase(StepType::Then); + let (alert, level) = alert_and_level.into(); + + let aircraft_states = + AircraftStateGenerator::default().take(world.test_length * world.constraints.len()); + + let n_constraints = world.constraints.len(); + for (c, mut frame) in aircraft_states + .enumerate() + .map(|(c, f)| (c % n_constraints, f)) + { + world.constraints[c].apply_to(&mut frame); + + let alert_state = world.taws.process(&mut frame); + // Make sure we are in the last phase of this scenario with "c + 1 == world.constraints.len()" + if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { + panic!( + "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", + frame, alert_state + ); + } + } +} + +#[then(regex = r"^a (.*) alert is emitted within ([0-9]+\.?[0-9]*) seconds$")] +fn is_emitted_within(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper, _seconds: f64) { + world.update_phase(StepType::Then); + let (alert, level) = alert_and_level.into(); + + let aircraft_states = + AircraftStateGenerator::default().take(world.test_length * world.constraints.len()); + + let n_constraints = world.constraints.len(); + for (c, mut frame) in aircraft_states + .enumerate() + .map(|(c, f)| (c % n_constraints, f)) + { + world.constraints[c].apply_to(&mut frame); + + let alert_state = world.taws.process(&mut frame); + // TODO what about the time constraint? + // Count all alerts that are from the functionality Mode1 and are of higher or + // same priority as `level`. If the count is 0, the system did not alert + // appropriately. + if c + 1 == n_constraints + && alert_state + .iter() + .filter(|(a, l)| *a == alert && *l <= level) + .count() + == 0 + { + panic!( + "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", + frame, alert_state + ); + } + } +} + +static AIRPORT_DATABASE: ConstraintAirportDatabase = ConstraintAirportDatabase {}; + +lazy_static::lazy_static! { + static ref TAWS_CONFIG: TawsConfig<'static> = TawsConfig{ + terrain_server: &AIRPORT_DATABASE, + max_climbrate: Velocity::new::(700.0), + max_climbrate_change: Acceleration::new::(100.0), + }; +} + +// Brot und Butter implementations +#[async_trait(?Send)] +impl cucumber::World for MyWorld { + type Error = Infallible; + + async fn new() -> Result { + Ok(Self { + taws: MinimalTaws::new(&TAWS_CONFIG), + constraints: vec![AircraftStateConstraints::default()], + test_length: 10, // TODO Increase should we be able to reduce the nearest_airport function from the aviation database + last_step_type: StepType::Given, + phase: 0, + }) + } +} + +impl MyWorld { + // Updates the current phase based on the current StepType + pub fn update_phase(&mut self, current_type: StepType) { + if self.last_step_type != current_type { + //Only increase phase if current phase is not "Then" + // Then-Step should not enforce AirplaneStateConstraints + if current_type != StepType::Then { + self.constraints.push(self.constraints[self.phase].clone()); + self.phase += 1; + } + + if self.last_step_type == StepType::Then && current_type == StepType::When { + panic!("Multiple When/Then Pairs are not allowed") + } + + self.last_step_type = current_type; + } + } +} + +impl std::fmt::Debug for MyWorld { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MyWorld").finish() + //todo!(); + } +} + +impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? diff --git a/taws_minimal/tests/util/constraint.rs b/taws_minimal/tests/util/constraint.rs new file mode 100644 index 0000000..b0f8825 --- /dev/null +++ b/taws_minimal/tests/util/constraint.rs @@ -0,0 +1,320 @@ +#[allow(dead_code)] +use crate::util::PressMould; +use crate::BouncingClamp; +use aviation_database::{AirportDatabase, Runway}; +use opentaws::AircraftState; +use uom::si::f64::*; + +#[derive(Clone, Default, PartialEq)] +pub struct AircraftStateConstraints { + altitude: Vec>, + altitude_ground: Vec>, + climb_rate: Vec>, + speed_air: Vec>, + heading: Vec>, + pitch: Vec>, + roll: Vec>, + //TODO use vector with bool and phase + steep_approach: bool, + precision_approach: bool, + go_around: bool, + take_of: bool, +} + +impl AircraftStateConstraints { + //Retains constraints from the current phase + fn filter_phase(constraints: &mut Vec>, current_phase: usize) + where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + crate::util::Abs + + std::fmt::Debug, + { + let mut i = 0; + while i < constraints.len() { + if constraints[i].phase() != current_phase { + constraints.remove(i); + } else { + i += 1; + } + } + } + + //Merges constraints + //Especially important for merging < and > constraints into one InRange constraint + fn merge(constraints: &[Constraint]) -> Vec> + where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + crate::util::Abs + + std::fmt::Debug, + { + let mut cs = Vec::new(); + let mut at_least = None; + let mut at_most = None; + + for c in constraints { + match c { + Constraint::AtLeast(_, q) => { + if at_least.map_or(true, |a| q > a) { + at_least = Some(q); + } + } + Constraint::AtMost(_, q) => { + if at_most.map_or(true, |a| q < a) { + at_most = Some(q); + } + } + Constraint::InRange(_, l, r) => { + if at_least.map_or(true, |a| l > a) { + at_least = Some(l); + } + if at_most.map_or(true, |a| r < a) { + at_most = Some(r); + } + } + _ => cs.push(c.clone()), + } + } + + match (at_least, at_most) { + (Some(at_least), Some(at_most)) => { + assert!( + at_least <= at_most, + "Left bound ({:?}) is greater than right bound ({:?})", + at_least, + at_most + ); + cs.push(Constraint::InRange( + constraints.first().unwrap().phase(), + *at_least, + *at_most, + )); + } + (Some(at_least), None) => cs.push(Constraint::AtLeast( + constraints.first().unwrap().phase(), + *at_least, + )), + (None, Some(at_most)) => cs.push(Constraint::AtMost( + constraints.first().unwrap().phase(), + *at_most, + )), + _ => {} + } + + cs + } + + fn apply(constraints: &[Constraint], state: &mut Q) + where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + crate::util::Abs + + std::fmt::Debug, + { + let merged = Self::merge(constraints); + for c in &merged { + c.apply_to(state) + } + for c in constraints { + c.check(*state) + } + } + + pub fn apply_to(&self, state: &mut AircraftState) { + Self::apply(&self.altitude, &mut state.altitude); + Self::apply(&self.altitude_ground, &mut state.altitude_ground); + Self::apply(&self.climb_rate, &mut state.climb_rate); + Self::apply(&self.speed_air, &mut state.speed_air); + Self::apply(&self.heading, &mut state.heading); + Self::apply(&self.pitch, &mut state.pitch); + Self::apply(&self.roll, &mut state.roll); + + //TODO Change when bools get vec + state.steep_approach = self.steep_approach; + state.precision_approach = self.precision_approach; + state.go_around = self.go_around; + state.take_off = self.take_of; + } + + pub fn add_altitude_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.altitude.push(c); + Self::filter_phase(self.altitude.as_mut(), phase) + } + + pub fn add_altitude_ground_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.altitude_ground.push(c); + Self::filter_phase(self.altitude_ground.as_mut(), phase) + } + + pub fn add_climb_rate_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.climb_rate.push(c); + Self::filter_phase(self.climb_rate.as_mut(), phase) + } + + pub fn add_speed_air_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.speed_air.push(c); + Self::filter_phase(self.speed_air.as_mut(), phase) + } + + pub fn add_heading_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.heading.push(c); + Self::filter_phase(self.heading.as_mut(), phase) + } + + pub fn add_pitch_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.pitch.push(c); + Self::filter_phase(self.pitch.as_mut(), phase) + } + + pub fn add_roll_constraint(&mut self, c: Constraint) { + let phase = c.phase(); + self.roll.push(c); + Self::filter_phase(self.roll.as_mut(), phase) + } + + pub fn add_steep_approach_constraint(&mut self, c: bool) { + self.steep_approach = c; + } + + pub fn add_precision_approach_constraint(&mut self, c: bool) { + self.precision_approach = c; + } + + pub fn add_go_around_constraint(&mut self, c: bool) { + self.go_around = c; + } + + pub fn add_take_off_constraint(&mut self, c: bool) { + self.take_of = c; + } +} + +#[derive(Clone, PartialEq, Debug)] +pub enum Constraint +where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + crate::util::Abs + + std::fmt::Debug, +{ + AtLeast(usize, Q), + AtMost(usize, Q), + Equal(usize, Q), + InRange(usize, Q, Q), + NotInRange(usize, Q, Q), +} + +impl Constraint +where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + crate::util::Abs + + std::fmt::Debug, +{ + pub fn phase(&self) -> usize { + match self { + Constraint::AtLeast(i, _) => *i, + Constraint::AtMost(i, _) => *i, + Constraint::Equal(i, _) => *i, + Constraint::InRange(i, _, _) => *i, + Constraint::NotInRange(i, _, _) => *i, + } + } + + pub fn apply_to(&self, quantity: &mut Q) { + let mut bouncer = BouncingClamp(); + + match self { + Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), + Constraint::AtMost(_, l) => bouncer.at_most(quantity, *l), + Constraint::Equal(_, l) => *quantity = *l, + Constraint::InRange(_, l, r) => bouncer.in_range(quantity, *l, *r), + Constraint::NotInRange(_, l, r) => bouncer.not_in_range(quantity, *l, *r), + } + } + + pub fn check(&self, to_check: Q) { + match self { + Constraint::AtLeast(_, l) => assert!( + to_check >= *l, + "Checked Number {:?} failed constraint: at least {:?}", + to_check, + l + ), + Constraint::AtMost(_, l) => assert!( + to_check <= *l, + "Checked Number {:?} failed constraint: at most {:?}", + to_check, + l + ), + Constraint::Equal(_, l) => assert_eq!( + &to_check, l, + "Checked Number {:?} failed constraint: equal to {:?}", + to_check, l + ), + Constraint::InRange(_, l, r) => assert!( + to_check >= *l && to_check <= *r, + "Checked Number {:?} failed constraint: in range {:?} - {:?}", + to_check, + l, + r + ), + Constraint::NotInRange(_, l, r) => assert!( + *l < to_check || to_check < *r, + "Checked Number {:?} failed constraint: not in range {:?} - {:?}", + to_check, + r, + l + ), + } + } +} + +#[derive(Debug, Default)] +pub struct ConstraintAirportDatabase; + +impl AirportDatabase for ConstraintAirportDatabase { + type RunwayIterator = core::iter::Empty; +} diff --git a/tests/util/mod.rs b/taws_minimal/tests/util/mod.rs similarity index 97% rename from tests/util/mod.rs rename to taws_minimal/tests/util/mod.rs index 5568b1e..2e03fc7 100644 --- a/tests/util/mod.rs +++ b/taws_minimal/tests/util/mod.rs @@ -1,3 +1,5 @@ +pub mod constraint; + use std::{ ops::{Add, Rem, Sub}, str::FromStr, @@ -31,6 +33,9 @@ impl<'a> Arbitrary<'a> for AircraftStateWrapper { pitch: Angle::new::(::arbitrary(u)? as f64), roll: Angle::new::(::arbitrary(u)? as f64), steep_approach: u.arbitrary()?, + precision_approach: u.arbitrary()?, + go_around: u.arbitrary()?, + take_off: u.arbitrary()?, })) } diff --git a/tests/cucumber.rs b/tests/cucumber.rs deleted file mode 100644 index 6e741c6..0000000 --- a/tests/cucumber.rs +++ /dev/null @@ -1,181 +0,0 @@ -use std::convert::Infallible; - -use uom::si::{f64::*, length::foot, velocity::foot_per_minute}; - -use cucumber_rust::{async_trait, given, then, when, WorldInit}; -use opentaws::prelude::*; - -mod util; -use util::*; - -fn main() { - let runner = MyWorld::init(&["./features"]); - futures::executor::block_on(runner.run()); -} - -#[derive(WorldInit)] -pub struct MyWorld { - taws: Taws, - moulds: Vec>, - test_length: usize, -} - -#[given("the plane is flying")] -fn is_flying(_world: &mut MyWorld) {} - -#[given(regex = r#"^(.+) is ?(not)? armed$"#)] -fn is_armed(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { - if maybe_not == "not" { - world.taws.disarm(alert.into()); - } else { - world.taws.arm(alert.into()); - } -} - -#[given(regex = "^(.+) is ?(not)? inhibited$")] -fn is_inhibited(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { - if maybe_not == "not" { - world.taws.uninhibit(alert.into()); - } else { - world.taws.inhibit(alert.into()); - } -} - -#[given(regex = r"^steep approach is ?(not)? selected$")] -fn steep_approach(world: &mut MyWorld, maybe_not: String) { - if maybe_not == "not" { - world.add_mould(|a| a.steep_approach = false); - } else { - world.add_mould(|a| a.steep_approach = true); - } -} - -#[then(regex = r"^(.+) shall be armed$")] -fn shall_be_armed(world: &mut MyWorld, alert: AlertWrapper) { - // TODO check if space needs to be removed - assert!(world.taws.is_armed(alert.into())); -} - -#[when(regex = r"^the rate of descent is at (most|least) (\d+) feet per minute$")] -fn rate_of_descent(world: &mut MyWorld, most_or_least: String, rod: f64) { - let rod = Velocity::new::(rod); - let mut bouncer = BouncingClamp(); - // most and least are swapped here, as aircraft_state stores rate of climb, while - // the sentence give rate of descent - // TODO validate that this is a safe assumption? - match most_or_least.as_str() { - "most" => { - world.add_mould(move |a| bouncer.at_least(&mut a.climb_rate, -rod)); - } - "least" => { - world.add_mould(move |a| bouncer.at_most(&mut a.climb_rate, -rod)); - } - _ => { - panic!("unable to parse this sentence"); - } - } -} - -#[when(regex = r"^the height above terrain is ?(not)? between (\d+) and (\d+) feet$")] -fn height_above_terrain(world: &mut MyWorld, maybe_not: String, lower: f64, upper: f64) { - let height_at_least = Length::new::(lower); - let height_at_most = Length::new::(upper); - - let mut bouncer = BouncingClamp(); - - if maybe_not == "not" { - world.add_mould(move |a| { - bouncer.not_in_range(&mut a.altitude_ground, height_at_least, height_at_most) - }); - } else { - world.add_mould(move |a| { - bouncer.in_range(&mut a.altitude_ground, height_at_least, height_at_most) - }); // TODO altitude or altitude_ground - } -} - -#[then(regex = "^a (.*) alert is not emitted at all$")] -fn is_not_emitted(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper) { - let (alert, level) = alert_and_level.into(); - let mut aircraft_states: Vec<_> = AircraftStateGenerator::default() - .take(world.test_length) - .collect(); - - // press the test data in our moulds - for frame in aircraft_states.iter_mut() { - for f in world.moulds.iter_mut() { - f(frame); - } - } - - for frame in aircraft_states { - let alert_state = world.taws.process(&frame); - if alert_state.iter().any(|(a, l)| a == alert && l <= level) { - panic!( - "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", - frame, alert_state - ); - } - } -} -#[then(regex = r"^a (.*) alert is emitted within (\d+) seconds$")] -fn is_emitted_within(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper, _seconds: f64) { - let (alert, level) = alert_and_level.into(); - let mut aircraft_states: Vec<_> = AircraftStateGenerator::default() - .take(world.test_length) - .collect(); - - // press the test data in our moulds - for frame in aircraft_states.iter_mut() { - for f in world.moulds.iter_mut() { - f(frame); - } - } - - for frame in aircraft_states { - let alert_state = world.taws.process(&frame); - // TODO what about the time constraint? - // Count all alerts that are from the functionality Mode1 and are of higher or - // same priority as `level`. If the count is 0, the system did not alert - // appropiately. - if alert_state - .iter() - .filter(|(a, l)| *a == alert && *l <= level) - .count() - == 0 - { - panic!( - "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", - frame, alert_state - ); - } - } -} - -// Brot und Butter implementations -#[async_trait(?Send)] -impl cucumber_rust::World for MyWorld { - type Error = Infallible; - - async fn new() -> Result { - Ok(Self { - taws: Taws::new(Default::default()), - moulds: Vec::new(), - test_length: 10000, // TODO is this a good number? - }) - } -} - -impl MyWorld { - pub fn add_mould(&mut self, f: F) { - self.moulds.push(Box::new(f)); - } -} - -impl std::fmt::Debug for MyWorld { - fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - todo!(); - } -} - -impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? From 672f67f8b423c90706ae390624a1585622e8115f Mon Sep 17 00:00:00 2001 From: autumnal Date: Fri, 26 Nov 2021 11:08:40 +0100 Subject: [PATCH 09/73] solve #20: clean up trait usage in `kd_tree` + replace `core::ops::*` by `num::traits::Num` + remove unnecessary trait bounds like `Sized` + break long comment lines --- kd_tree/src/lib.rs | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/kd_tree/src/lib.rs b/kd_tree/src/lib.rs index 5a861aa..72318d6 100644 --- a/kd_tree/src/lib.rs +++ b/kd_tree/src/lib.rs @@ -2,14 +2,13 @@ #![allow(clippy::too_many_arguments)] use core::cmp::Ordering; use core::fmt::Debug; -use core::ops::{Add, Mul, Sub}; -use num::traits::Zero; +use num::traits::Num; -pub struct Tree { +pub struct Tree { pub nodes: [Node; SIZE], } -impl +impl Tree { pub const fn new(nodes: [Node; SIZE]) -> Tree { @@ -18,17 +17,8 @@ impl - + Add - + Mul - + Zero - + Copy - + Debug - + Default, - V: Sized, + T: PartialOrd + Num + Copy + Debug, + V, const SIZE: usize, const DIM: usize, const MAX_LEVEL: usize, @@ -41,7 +31,8 @@ impl< .expect("This can not fail, expect if the Tree got no nodes: SIZE == 0"); let mut index = 0usize; let mut level = 0usize; - // Store which child nodes where visited for the Node on the index/level and if it was already compared + // Store which child nodes where visited for the Node on the index/level and if it was + // already compared let mut visited: [(Visited, bool); MAX_LEVEL] = [(Visited::None, false); MAX_LEVEL]; //Initialise best node/distance with root node let mut best_distance: T = euclid(&node.val, point); @@ -52,7 +43,8 @@ impl< self.search_down(point, &mut node, &mut index, &mut level, &mut visited); // Go up until we either reach the top or we go down by one - // Should we go down by one, we will need to go to the best fit leaf of the current subtree + // Should we go down by one, we will need to go to the best fit leaf of the current + // subtree self.search_up( point, &mut node, @@ -242,7 +234,7 @@ pub struct Node { v: V, } -impl Node { +impl Node { pub fn val(&self) -> &[T; DIM] { &self.val } @@ -258,7 +250,7 @@ impl Node { pub fn euclid(left: &[T; SIZE], right: &[T; SIZE]) -> T where - T: Default + Add + Sub + Mul + Zero + Copy + Debug, + T: Num + Copy + Debug, { left.iter() .zip(right.iter()) From a394a36bbc9d95341e0fc6a8b411e0048cf850e4 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Fri, 26 Nov 2021 15:59:47 +0100 Subject: [PATCH 10/73] solve #21 partially + add nicer error message if `airports.json` doesn't exist + remove `SIZE` const generic from Tree --- aviation_database/build.rs | 7 +++--- kd_tree/src/lib.rs | 31 ++++++++++-------------- kd_tree_sort/src/lib.rs | 48 +++++++++++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/aviation_database/build.rs b/aviation_database/build.rs index 2350695..dcfb51a 100644 --- a/aviation_database/build.rs +++ b/aviation_database/build.rs @@ -81,7 +81,7 @@ fn main() { //let airports = File::open("airports.json").unwrap(); //let mut reader = BufReader::new(airports); - let read = std::fs::read_to_string("airports.json").unwrap(); + let read = std::fs::read_to_string("airports.json").expect("Download Airports json:\nhttps://datahub.io/core/airport-codes/r/airport-codes.json\nAnd place it next to build.rs"); let mut airports: Vec = serde_json::from_str(&read).unwrap(); let num_airports = airports.len(); let out_dir = env::var_os("OUT_DIR").unwrap(); @@ -110,8 +110,9 @@ fn main() { fs::write( &dest_path, format!( - "pub const AIRPORTS: Tree:: = Tree::new([ {} ]);", - num_airports, max_level, airports + "pub const NODES: [Node; {}] = [ {} ];\ + pub const AIRPORTS: Tree:: = Tree::new( &NODES );", + num_airports, airports, max_level ), ) .unwrap(); diff --git a/kd_tree/src/lib.rs b/kd_tree/src/lib.rs index 72318d6..28c402a 100644 --- a/kd_tree/src/lib.rs +++ b/kd_tree/src/lib.rs @@ -4,25 +4,18 @@ use core::cmp::Ordering; use core::fmt::Debug; use num::traits::Num; -pub struct Tree { - pub nodes: [Node; SIZE], +pub struct Tree<'a, T, V, const DIM: usize, const MAX_LEVEL: usize> { + pub nodes: &'a [Node], } -impl - Tree -{ - pub const fn new(nodes: [Node; SIZE]) -> Tree { +impl Tree<'static, T, V, DIM, MAX_LEVEL> { + pub const fn new(nodes: &'static [Node]) -> Tree<'static, T, V, DIM, MAX_LEVEL> { Tree { nodes } } } -impl< - T: PartialOrd + Num + Copy + Debug, - V, - const SIZE: usize, - const DIM: usize, - const MAX_LEVEL: usize, - > Tree +impl<'a, T: PartialOrd + Num + Copy + Debug, V, const DIM: usize, const MAX_LEVEL: usize> + Tree<'a, T, V, DIM, MAX_LEVEL> { pub fn search(&self, point: &[T; DIM]) -> &Node { let mut node: &Node = self @@ -65,7 +58,7 @@ impl< best_node } - fn search_down<'a>( + fn search_down( &'a self, point: &[T; DIM], node: &mut &'a Node, @@ -81,7 +74,7 @@ impl< let dim = *level % DIM; //If the left node is not reachable we are at a leaf node - if left(index) >= SIZE { + if left(index) >= self.nodes.len() { //Set visited for this level to ALL because there are no more child nodes visited[*level].0 = Visited::All; return; @@ -95,7 +88,7 @@ impl< // If the index is to big we choose the right node // Make sure it exists, if not go to the left node instead - if *index >= SIZE { + if *index >= self.nodes.len() { *index -= 1; } @@ -107,7 +100,7 @@ impl< } } - fn search_up<'a>( + fn search_up( &'a self, point: &[T; DIM], node: &mut &'a Node, @@ -138,7 +131,7 @@ impl< // and if its even possible for the right side to be nearer let single_distance = point[dim] - node.val[dim]; let single_distance = single_distance * single_distance; - if right(index) < SIZE && single_distance < *best_distance { + if right(index) < self.nodes.len() && single_distance < *best_distance { Direction::Right } else { Direction::Up @@ -149,7 +142,7 @@ impl< // and if its even possible for the left side to be nearer let single_distance = point[dim] - node.val[dim]; let single_distance = single_distance * single_distance; - if left(index) < SIZE && single_distance < *best_distance { + if left(index) < self.nodes.len() && single_distance < *best_distance { Direction::Left } else { Direction::Up diff --git a/kd_tree_sort/src/lib.rs b/kd_tree_sort/src/lib.rs index 44967ff..50a553e 100644 --- a/kd_tree_sort/src/lib.rs +++ b/kd_tree_sort/src/lib.rs @@ -110,11 +110,11 @@ mod tests { let nodes = sorted .iter() .map(|(p, v)| Node::new(*p, *v)) - .collect::>() - .try_into() - .unwrap(); + .collect::>(); //T, V, SIZE, DIM, MAX_LEVEL - let tree = Tree::::new(nodes); + let tree = Tree:: { + nodes: nodes.as_slice(), + }; assert_eq!(tree.search(&[5, 3]).val(), &[5, 4]); assert_eq!(tree.search(&[9, 7]).val(), &[9, 6]); @@ -122,15 +122,18 @@ mod tests { assert_eq!(tree.search(&[3, 0]).val(), &[2, 3]); } - #[ignore] #[test] fn random_search() { let mut rng = Prng::new(0xcafef00dd15ea5e5); + let mut duration_linear_min = Duration::from_secs(9999); let mut duration_linear = Duration::from_secs(0); + let mut duration_linear_max = Duration::from_secs(0); + let mut duration_tree_min = Duration::from_secs(9999); let mut duration_tree = Duration::from_secs(0); + let mut duration_tree_max = Duration::from_secs(0); let (iterations, searches) = if cfg!(debug_assertions) { - (10, 50) + (10, 500) } else { (100, 500) }; @@ -151,9 +154,10 @@ mod tests { .collect(); let sorted = sort(values.clone()); let nodes: Vec<_> = sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect(); - let tree: Box> = Box::new(Tree { - nodes: nodes.try_into().unwrap(), - }); + let tree = Tree:: { + nodes: nodes.as_slice(), + }; + let search_points: Vec<[f64; 3]> = std::iter::repeat_with(|| [rng.gen(), rng.gen(), rng.gen()]) .take(searches) @@ -165,15 +169,37 @@ mod tests { .map(|a| euclid(&point, &a.0)) .min_by(|a, b| a.partial_cmp(b).unwrap()) .unwrap(); - duration_linear.add_assign(now.elapsed()); + let lin_dur = now.elapsed(); let now = Instant::now(); let closest_node = tree.search(&point); - duration_tree.add_assign(now.elapsed()); + let tree_dur = now.elapsed(); assert_eq!(closest, euclid(closest_node.val(), &point),); + + duration_linear.add_assign(lin_dur); + if lin_dur < duration_linear_min { + duration_linear_min = lin_dur + } else if lin_dur > duration_linear_max { + duration_linear_max = lin_dur + } + + duration_tree.add_assign(tree_dur); + if tree_dur < duration_tree_min { + duration_tree_min = tree_dur + } else if tree_dur > duration_tree_max { + duration_tree_max = tree_dur + } } } println!("Duration Linear Search: {:?}", duration_linear); println!("Duration KD Tree Search: {:?}", duration_tree); + println!( + "{:.2}x increase in performance", + duration_linear.as_micros() as f64 / duration_tree.as_micros() as f64 + ); + println!("\nFastest KD Tree Search: {:?}", duration_tree_min); + println!("Slowest KD Tree Search: {:?}", duration_tree_max); + println!("Fastest Linear Search: {:?}", duration_linear_min); + println!("Slowest Linear Search: {:?}", duration_linear_max); } } From 138f24fffda5dc7b9dc22d8113d337d9a67664ed Mon Sep 17 00:00:00 2001 From: wucke13 Date: Fri, 26 Nov 2021 16:36:44 +0100 Subject: [PATCH 11/73] allow test & coverage failure on pr to staging --- .github/workflows/rust.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e5d10e8..6ca219d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: main on: push: - branches: [ main ] + branches: [ main, staging ] pull_request: - branches: [ main ] + branches: [ main, staging ] jobs: format: @@ -16,12 +16,17 @@ jobs: toolchain: stable components: rustfmt override: true - - uses: mbrobbel/rustfmt-check@0.2.0 + - uses: actions-rs/toolchain@v1 with: - token: ${{ secrets.GITHUB_TOKEN }} + toolchain: stable + target: x86_64-unknown-linux-gnu + override: true + - name: Run tests + run: cargo fmt -- --check test: runs-on: ubuntu-latest + continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name == 'staging' }} steps: - uses: actions/checkout@v2 - uses: actions/cache@v2 @@ -37,7 +42,7 @@ jobs: target: x86_64-unknown-linux-gnu override: true - name: Run tests - run: cargo test --verbose + run: cargo test --all-features --verbose clippy_check: runs-on: ubuntu-latest @@ -63,6 +68,7 @@ jobs: coverage: name: coverage runs-on: ubuntu-latest + continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name == 'staging' }} container: image: xd009642/tarpaulin:latest options: --security-opt seccomp=unconfined @@ -86,4 +92,4 @@ jobs: - name: Upload to codecov.io uses: codecov/codecov-action@v1 with: - fail_ci_if_error: true + fail_ci_if_error: true From d0ca40c7d0775fa693ee5b48454fde6075cc15c9 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Fri, 26 Nov 2021 19:22:45 +0100 Subject: [PATCH 12/73] add automatic download of airports.json + also provides two env variables: `AIRPORTS_JSON_FILE` & `AIRPORTS_JSON_URL` + these can be used to specify from where to pull the airports.json --- Cargo.lock | 85 ++++++++++++++++++++++++++++++++++++ aviation_database/Cargo.toml | 21 ++++----- aviation_database/build.rs | 36 ++++++++++++--- 3 files changed, 125 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f348bbf..d21c106 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,6 +256,7 @@ dependencies = [ "serde_json", "uneval", "uom", + "ureq", ] [[package]] @@ -350,6 +351,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + [[package]] name = "clap" version = "2.33.3" @@ -1357,6 +1364,21 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "ringbuffer" version = "0.8.3" @@ -1366,6 +1388,18 @@ dependencies = [ "array-init", ] +[[package]] +name = "rustls" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "ryu" version = "1.0.5" @@ -1387,6 +1421,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sealed" version = "0.3.0" @@ -1731,6 +1775,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "uom" version = "0.31.1" @@ -1742,6 +1792,22 @@ dependencies = [ "typenum", ] +[[package]] +name = "ureq" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5c448dcb78ec38c7d59ec61f87f70a98ea19171e06c139357e012ee226fec90" +dependencies = [ + "base64", + "chunked_transfer", + "log", + "once_cell", + "rustls", + "url", + "webpki", + "webpki-roots", +] + [[package]] name = "url" version = "2.2.2" @@ -1881,6 +1947,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c475786c6f47219345717a043a37ec04cb4bc185e28853adcc4fa0a947eba630" +dependencies = [ + "webpki", +] + [[package]] name = "wepoll-ffi" version = "0.1.2" diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml index 2fae125..7145667 100644 --- a/aviation_database/Cargo.toml +++ b/aviation_database/Cargo.toml @@ -6,20 +6,21 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -uom = "0.31" ordered-float = { version = "2.0", default-features = false } +uom = "0.31" kd_tree = { path = "../kd_tree" } [build-dependencies] -kd_tree_sort = { path = "../kd_tree_sort" } -uom = "0.31" -uneval = "0.2" -serde = {version = "1.0", features = ["derive"]} -serde_json = "1.0" -rayon = "1.5" -quote = "1.0" +anyhow = "1.0" +csv = "1.1" proc-macro2 = "1.0" +quote = "1.0" +rayon = "1.5" regex = "1.5" -csv = "1.1" -anyhow = "1.0" +serde = {version = "1.0", features = ["derive"]} +serde_json = "1.0" +uneval = "0.2" +uom = "0.31" +ureq = "2" +kd_tree_sort = { path = "../kd_tree_sort" } diff --git a/aviation_database/build.rs b/aviation_database/build.rs index dcfb51a..7acf772 100644 --- a/aviation_database/build.rs +++ b/aviation_database/build.rs @@ -4,6 +4,7 @@ use rayon::prelude::*; use serde::Deserialize; use std::env; use std::fs; +use std::io::BufRead; use std::path::Path; use std::process::Command; @@ -76,13 +77,28 @@ impl ToTokens for Airport { } fn main() { - // Downloaded directly from: - // https://datahub.io/core/airport-codes/r/airport-codes.json - //let airports = File::open("airports.json").unwrap(); - //let mut reader = BufReader::new(airports); + let file_env = "AIRPORTS_JSON_FILE"; + let url_env = "AIRPORTS_JSON_URL"; + + let reader: Box = if let Ok(airports_file) = std::env::var(file_env) { + let f = std::fs::File::open(&airports_file) + .expect(&format!("file {} does not exist", airports_file)); + Box::new(std::io::BufReader::new(f)) + } else { + let airports_url = std::env::var(url_env) + .unwrap_or("https://datahub.io/core/airport-codes/r/airport-codes.json".into()); + let r = ureq::get(&airports_url) + .call() + .expect(&format!( + "unable to automatically download from {}", + airports_url + )) + .into_reader(); + Box::new(std::io::BufReader::new(r)) + }; + + let mut airports: Vec = serde_json::from_reader(reader).unwrap(); - let read = std::fs::read_to_string("airports.json").expect("Download Airports json:\nhttps://datahub.io/core/airport-codes/r/airport-codes.json\nAnd place it next to build.rs"); - let mut airports: Vec = serde_json::from_str(&read).unwrap(); let num_airports = airports.len(); let out_dir = env::var_os("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("airports.rs"); @@ -126,5 +142,11 @@ fn main() { eprintln!("{}", e) } - println!("cargo:rerun-if-changed=build.rs"); + println!( + "cargo:rerun-if-changed=build.rs + cargo:rerun-if-env-changed={} + cargo:rerun-if-env-changed={} + ", + url_env, file_env + ); } From 0e1c94c3c745556170ffd6c3dd58e585f414fcf8 Mon Sep 17 00:00:00 2001 From: autumnal Date: Fri, 26 Nov 2021 16:08:15 +0100 Subject: [PATCH 13/73] kd tree benchmark - solve #18 partially --- Cargo.lock | 211 ++++++++++++++++++++++++--------- kd_tree_sort/Cargo.toml | 6 + kd_tree_sort/benches/search.rs | 59 +++++++++ 3 files changed, 223 insertions(+), 53 deletions(-) create mode 100644 kd_tree_sort/benches/search.rs diff --git a/Cargo.lock b/Cargo.lock index d21c106..615641b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,15 +22,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.45" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" +checksum = "ecc78c299ae753905840c5d3ba036c51f61ce5a98a83f98d9c9d29dffd427f71" [[package]] name = "arbitrary" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577b08a4acd7b99869f863c50011b01eb73424ccc798ecd996f2e24817adfca7" +checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" dependencies = [ "derive_arbitrary", ] @@ -339,6 +339,15 @@ dependencies = [ "syn", ] +[[package]] +name = "cast" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" +dependencies = [ + "rustc_version", +] + [[package]] name = "cc" version = "1.0.72" @@ -405,6 +414,42 @@ dependencies = [ "libc", ] +[[package]] +name = "criterion" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +dependencies = [ + "cast", + "itertools", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -532,9 +577,9 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.16" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", @@ -595,9 +640,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" dependencies = [ "futures-channel", "futures-core", @@ -610,9 +655,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" dependencies = [ "futures-core", "futures-sink", @@ -620,15 +665,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" dependencies = [ "futures-core", "futures-task", @@ -637,9 +682,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" [[package]] name = "futures-lite" @@ -658,12 +703,10 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -671,23 +714,22 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -697,8 +739,6 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -788,6 +828,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "heck" version = "0.3.3" @@ -924,6 +970,8 @@ dependencies = [ name = "kd_tree_sort" version = "0.1.0" dependencies = [ + "criterion", + "itertools", "kd_tree", "rand", "rand_pcg", @@ -950,9 +998,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.107" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "linked-hash-map" @@ -1082,6 +1130,12 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1185,6 +1239,34 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "plotters" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" + +[[package]] +name = "plotters-svg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polling" version = "2.2.0" @@ -1228,18 +1310,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "1.0.32" @@ -1381,13 +1451,22 @@ dependencies = [ [[package]] name = "ringbuffer" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e49d3a791d79aa7683f8798b274073140865ffb9d65767ace44229d34299e3" +checksum = "72dfeba9c94fdc308dcfe165efa6855c698f317484b736605ff859c5fa81d992" dependencies = [ "array-init", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.20.2" @@ -1402,9 +1481,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" [[package]] name = "same-file" @@ -1443,6 +1522,12 @@ dependencies = [ "syn", ] +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + [[package]] name = "serde" version = "1.0.130" @@ -1461,6 +1546,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.130" @@ -1474,9 +1569,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", @@ -1593,9 +1688,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -1681,6 +1776,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.5.1" @@ -1734,9 +1839,9 @@ checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "uneval" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b95ceb1224b9d137ee19530b0d6f39c66d73098b50d41a4de4ccbf5e4f122" +checksum = "18af63a2eefd8deddc36dd58844ee014aca201861e8bacf8da916369df78d4da" dependencies = [ "serde", "thiserror", diff --git a/kd_tree_sort/Cargo.toml b/kd_tree_sort/Cargo.toml index 449c57a..cfb5832 100644 --- a/kd_tree_sort/Cargo.toml +++ b/kd_tree_sort/Cargo.toml @@ -12,3 +12,9 @@ rayon = "1.5" [dev-dependencies] rand = "0.8" rand_pcg = "*" +itertools = "0.10" +criterion = "0.3" + +[[bench]] +name = "search" +harness = false diff --git a/kd_tree_sort/benches/search.rs b/kd_tree_sort/benches/search.rs new file mode 100644 index 0000000..42da518 --- /dev/null +++ b/kd_tree_sort/benches/search.rs @@ -0,0 +1,59 @@ +use std::time::Duration; +use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId, BatchSize}; +use kd_tree::{euclid, Node, Tree}; +use rand::Rng; +use kd_tree_sort::sort; + +type Prng = rand_pcg::Mcg128Xsl64; + +fn linear_search(nodes: &[Node], point: &[f64; 3]) -> f64 { + nodes + .iter() + .map(|a| euclid(point, a.val())) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() +} + +fn generate_values(len: usize, rng: &mut Prng) -> Vec<([f64; 3], i32)> { + (0..len) + .map(|_| (generate_point(rng), 0)) + .collect() +} + +fn generate_sorted(len: usize, rng: &mut Prng) -> Vec>{ + let sorted = sort(generate_values(len, rng)); + sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect() +} + +fn generate_point(rng: &mut Prng) -> [f64; 3]{ + [rng.gen(), rng.gen(), rng.gen()] +} + +pub fn search(c: &mut Criterion) { + let mut rng = Prng::new(0xcafef00dd15ea5e5); + + const START_LEN: usize = 1000; + const END_LEN: usize = 64001; + + const MAX_LEVEL: usize = 16; + + let mut group = c.benchmark_group("Search"); + group.warm_up_time(Duration::from_millis(50)); + group.measurement_time(Duration::from_secs(1)); + + for len in (START_LEN..END_LEN).step_by(1000){ + let nodes = generate_sorted(len, &mut rng); + let tree = Tree:: { + nodes: nodes.as_slice() + }; + group.bench_with_input(BenchmarkId::new("KD Tree", len), + &tree, |b, t| + b.iter_batched(|| generate_point(&mut rng),|p| t.search(&p), BatchSize::SmallInput)); + group.bench_with_input(BenchmarkId::new("Linear", len), + &nodes, |b, n| + b.iter_batched(|| generate_point(&mut rng),|p| linear_search(n, &p), BatchSize::SmallInput)); + } +} + +criterion_group!(benches, search); +criterion_main!(benches); \ No newline at end of file From b8fa162d10134d8f47d3b3bde3eaa4e49bd3bb94 Mon Sep 17 00:00:00 2001 From: Autumnal Date: Mon, 29 Nov 2021 15:20:26 +0100 Subject: [PATCH 14/73] Add fuzzy test and Readme; solves #18 --- kd_tree/README.md | 8 + kd_tree_sort/Cargo.toml | 3 + kd_tree_sort/README.md | 19 ++ kd_tree_sort/benches/search.rs | 40 ++- kd_tree_sort/fuzz/.gitignore | 3 + kd_tree_sort/fuzz/Cargo.lock | 303 ++++++++++++++++++ kd_tree_sort/fuzz/Cargo.toml | 28 ++ .../fuzz/fuzz_targets/kd_tree_search.rs | 55 ++++ 8 files changed, 442 insertions(+), 17 deletions(-) create mode 100644 kd_tree/README.md create mode 100644 kd_tree_sort/README.md create mode 100644 kd_tree_sort/fuzz/.gitignore create mode 100644 kd_tree_sort/fuzz/Cargo.lock create mode 100644 kd_tree_sort/fuzz/Cargo.toml create mode 100644 kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs diff --git a/kd_tree/README.md b/kd_tree/README.md new file mode 100644 index 0000000..40d6dc6 --- /dev/null +++ b/kd_tree/README.md @@ -0,0 +1,8 @@ +# KD-Tree implementation + +Implements only functions required for searching an already initialized KD-Tree. +Because of this, this crate is no_std compatible + +Code for building the KD-Tree can be found in `kd_tree_sort`. +`kd_tree_sort` is not no_std compatible which is why these two crates were seperated. +A fuzzy tester as well as a benchmark verifying this implementation can be found in `kd_tree_sort`. \ No newline at end of file diff --git a/kd_tree_sort/Cargo.toml b/kd_tree_sort/Cargo.toml index cfb5832..9dbb41c 100644 --- a/kd_tree_sort/Cargo.toml +++ b/kd_tree_sort/Cargo.toml @@ -15,6 +15,9 @@ rand_pcg = "*" itertools = "0.10" criterion = "0.3" +[lib] +bench = false + [[bench]] name = "search" harness = false diff --git a/kd_tree_sort/README.md b/kd_tree_sort/README.md new file mode 100644 index 0000000..8c28be9 --- /dev/null +++ b/kd_tree_sort/README.md @@ -0,0 +1,19 @@ +# KD-Tree sort implemention + +Implements a non-no_std compatible sort function for usage with the `kd_tree` crate. + +## Benchmark +For benchmarking purposed, criterion.rs was used, comparing our kd-tree against a basic linear_search. + +Run: `cargo bench` in this directory. + +## Fuzzy Test +The implemented fuzzy test uses `cargo fuzz` +Install it before running the fuzzy test (a nightly toolchain may be required). + +It compares the result of the linear search algorithm against the result of the kd-tree search. +The fuzzy test input is filtering out `Inf` and `NaN` values since our kd-tree is +supposed to find the nearest-neighbor on valid input data only. + +For starting the fuzzy test run: `cargo fuzz run kd_tree_search --sanitizer=leak` in this directory. +*Note: the fuzzy test will run until it finds an error* \ No newline at end of file diff --git a/kd_tree_sort/benches/search.rs b/kd_tree_sort/benches/search.rs index 42da518..68f8883 100644 --- a/kd_tree_sort/benches/search.rs +++ b/kd_tree_sort/benches/search.rs @@ -1,8 +1,8 @@ -use std::time::Duration; -use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId, BatchSize}; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use kd_tree::{euclid, Node, Tree}; -use rand::Rng; use kd_tree_sort::sort; +use rand::Rng; +use std::time::Duration; type Prng = rand_pcg::Mcg128Xsl64; @@ -15,17 +15,15 @@ fn linear_search(nodes: &[Node], point: &[f64; 3]) -> f64 { } fn generate_values(len: usize, rng: &mut Prng) -> Vec<([f64; 3], i32)> { - (0..len) - .map(|_| (generate_point(rng), 0)) - .collect() + (0..len).map(|_| (generate_point(rng), 0)).collect() } -fn generate_sorted(len: usize, rng: &mut Prng) -> Vec>{ +fn generate_sorted(len: usize, rng: &mut Prng) -> Vec> { let sorted = sort(generate_values(len, rng)); sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect() } -fn generate_point(rng: &mut Prng) -> [f64; 3]{ +fn generate_point(rng: &mut Prng) -> [f64; 3] { [rng.gen(), rng.gen(), rng.gen()] } @@ -41,19 +39,27 @@ pub fn search(c: &mut Criterion) { group.warm_up_time(Duration::from_millis(50)); group.measurement_time(Duration::from_secs(1)); - for len in (START_LEN..END_LEN).step_by(1000){ + for len in (START_LEN..END_LEN).step_by(1000) { let nodes = generate_sorted(len, &mut rng); let tree = Tree:: { - nodes: nodes.as_slice() + nodes: nodes.as_slice(), }; - group.bench_with_input(BenchmarkId::new("KD Tree", len), - &tree, |b, t| - b.iter_batched(|| generate_point(&mut rng),|p| t.search(&p), BatchSize::SmallInput)); - group.bench_with_input(BenchmarkId::new("Linear", len), - &nodes, |b, n| - b.iter_batched(|| generate_point(&mut rng),|p| linear_search(n, &p), BatchSize::SmallInput)); + group.bench_with_input(BenchmarkId::new("KD Tree", len), &tree, |b, t| { + b.iter_batched( + || generate_point(&mut rng), + |p| t.search(&p), + BatchSize::SmallInput, + ) + }); + group.bench_with_input(BenchmarkId::new("Linear", len), &nodes, |b, n| { + b.iter_batched( + || generate_point(&mut rng), + |p| linear_search(n, &p), + BatchSize::SmallInput, + ) + }); } } criterion_group!(benches, search); -criterion_main!(benches); \ No newline at end of file +criterion_main!(benches); diff --git a/kd_tree_sort/fuzz/.gitignore b/kd_tree_sort/fuzz/.gitignore new file mode 100644 index 0000000..a092511 --- /dev/null +++ b/kd_tree_sort/fuzz/.gitignore @@ -0,0 +1,3 @@ +target +corpus +artifacts diff --git a/kd_tree_sort/fuzz/Cargo.lock b/kd_tree_sort/fuzz/Cargo.lock new file mode 100644 index 0000000..1ed5d69 --- /dev/null +++ b/kd_tree_sort/fuzz/Cargo.lock @@ -0,0 +1,303 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arbitrary" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "derive_arbitrary" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "kd_tree" +version = "0.1.0" +dependencies = [ + "num", +] + +[[package]] +name = "kd_tree_sort" +version = "0.1.0" +dependencies = [ + "kd_tree", + "rayon", +] + +[[package]] +name = "kd_tree_sort-fuzz" +version = "0.0.0" +dependencies = [ + "arbitrary", + "kd_tree", + "kd_tree_sort", + "libfuzzer-sys", + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "proc-macro2" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "syn" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/kd_tree_sort/fuzz/Cargo.toml b/kd_tree_sort/fuzz/Cargo.toml new file mode 100644 index 0000000..4f84664 --- /dev/null +++ b/kd_tree_sort/fuzz/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "kd_tree_sort-fuzz" +version = "0.0.0" +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" +arbitrary = { version = "1", features = ["derive"] } +rayon = "1.5" + +[dependencies.kd_tree_sort] +path = ".." +[dependencies.kd_tree] +path = "../../kd_tree" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "kd_tree_search" +path = "fuzz_targets/kd_tree_search.rs" +test = false +doc = false diff --git a/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs b/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs new file mode 100644 index 0000000..9fc928b --- /dev/null +++ b/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs @@ -0,0 +1,55 @@ +#![no_main] +use kd_tree::{euclid, Node, Tree}; +use kd_tree_sort::sort; +use libfuzzer_sys::fuzz_target; +use rayon::prelude::*; + +#[derive(Clone, Debug, arbitrary::Arbitrary)] +struct ArbitraryPoint { + pos: [f64; 3], + p: i32, +} + +unsafe impl Sync for ArbitraryPoint{} +unsafe impl Send for ArbitraryPoint{} + +fn linear_search(nodes: &[Node], point: &[f64; 3]) -> f64 { + nodes + .iter() + .map(|a| euclid(point, a.val())) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() +} + +const MAX_LEVEL: usize = 16; + +fuzz_target!(|data: Vec| { + let mut data = data; + let mut data: Vec<_> = data + .drain(..) + .filter(|p| p.pos[0].is_finite() && p.pos[1].is_finite() && p.pos[2].is_finite()) + .take((2usize.pow(MAX_LEVEL as u32) - 1) * 2) + .par_bridge() + .map(|p| (p.pos, p.p)) + .collect(); + + if data.len() < 2 { + // Dont fuzzy test less than two elements + return; + } + + let search_data: Vec<_> = data.split_off(data.len() / 2); + + let sorted = sort(data); + let sorted: Vec<_> = sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect(); + let tree = Tree:: { + nodes: sorted.as_slice(), + }; + + search_data.par_iter().for_each(|(p, _)| { + assert_eq!( + euclid(tree.search(&p).val(), &p), + linear_search(&sorted, &p) + ) + }); +}); From a7df2babd3490834771b8bbfd2026a9a20215b66 Mon Sep 17 00:00:00 2001 From: wucke13 Date: Wed, 8 Jun 2022 11:41:52 +0200 Subject: [PATCH 15/73] fix compilation with uom issue --- Cargo.lock | 589 +++++++++++++++++++---------------- aviation_database/Cargo.toml | 4 +- opentaws/Cargo.toml | 4 +- taws_minimal/Cargo.toml | 4 +- 4 files changed, 328 insertions(+), 273 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 615641b..f4fd4d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.18" @@ -13,24 +19,24 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "anyhow" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc78c299ae753905840c5d3ba036c51f61ce5a98a83f98d9c9d29dffd427f71" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "arbitrary" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" +checksum = "c38b6b6b79f671c25e1a3e785b7b82d7562ffc9cd3efdc98627e5668a2472490" dependencies = [ "derive_arbitrary", ] @@ -79,25 +85,24 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" +checksum = "fd8b508d585e01084059b60f06ade4cb7415cd2e4084b71dd1cb44e7d3fb9880" dependencies = [ "async-channel", "async-executor", "async-io", - "async-mutex", + "async-lock", "blocking", "futures-lite", - "num_cpus", "once_cell", ] [[package]] name = "async-io" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" dependencies = [ "concurrent-queue", "futures-lite", @@ -114,18 +119,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-mutex" -version = "1.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" dependencies = [ "event-listener", ] @@ -143,9 +139,9 @@ dependencies = [ [[package]] name = "async-process" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" +checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" dependencies = [ "async-io", "blocking", @@ -160,9 +156,9 @@ dependencies = [ [[package]] name = "async-std" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" +checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" dependencies = [ "async-channel", "async-global-executor", @@ -187,15 +183,15 @@ dependencies = [ [[package]] name = "async-task" -version = "4.0.3" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" +checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" [[package]] name = "async-trait" -version = "0.1.51" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" dependencies = [ "proc-macro2", "quote", @@ -204,9 +200,9 @@ dependencies = [ [[package]] name = "async-tungstenite" -version = "0.16.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d06e9a20f1c0d64b6067ef6aa9fdf59e194ecde93575591fb4c78063692324" +checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" dependencies = [ "async-std", "futures-io", @@ -235,9 +231,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "aviation_database" @@ -273,18 +269,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ "generic-array", ] [[package]] name = "blocking" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" +checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" dependencies = [ "async-channel", "async-task", @@ -308,9 +304,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "byteorder" @@ -326,9 +322,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cache-padded" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "casey" @@ -350,9 +346,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -368,9 +364,9 @@ checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -407,13 +403,22 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.3.5" @@ -452,9 +457,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if", "crossbeam-utils", @@ -473,10 +478,11 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ + "autocfg", "cfg-if", "crossbeam-utils", "lazy_static", @@ -486,14 +492,24 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if", "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "csv" version = "1.1.6" @@ -502,7 +518,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ "bstr", "csv-core", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] @@ -518,9 +534,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", "syn", @@ -566,9 +582,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" +checksum = "98e23c06c035dac87bd802d98f368df73a7f2cb05a66ffbd1f377e821fac4af9" dependencies = [ "proc-macro2", "quote", @@ -588,11 +604,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "generic-array", + "block-buffer", + "crypto-common", ] [[package]] @@ -609,19 +626,29 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "event-listener" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" [[package]] name = "fastrand" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -640,9 +667,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -655,9 +682,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -665,15 +692,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -682,9 +709,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-lite" @@ -703,9 +730,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2", "quote", @@ -714,21 +741,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.18" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -744,9 +771,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -754,9 +781,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -782,9 +809,9 @@ dependencies = [ [[package]] name = "ghost" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5bcf1bbeab73aa4cf2fde60a846858dc036163c7c33bec309f8d17de785479" +checksum = "76c813ffb63e8fd3df6f1ac3cc1ea392c7612ac2de4d0b44dcbfe03e5c4bf94a" dependencies = [ "proc-macro2", "quote", @@ -817,15 +844,14 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" dependencies = [ "futures-channel", "futures-core", "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] @@ -854,20 +880,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.2", ] [[package]] name = "httparse" -version = "1.5.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "idna" @@ -937,9 +963,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] @@ -950,11 +976,17 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] @@ -998,30 +1030,27 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.108" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] -name = "linked-hash-map" -version = "0.5.4" +name = "libm" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] -name = "lock_api" -version = "0.4.5" +name = "linked-hash-map" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", "value-bag", @@ -1035,19 +1064,28 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + [[package]] name = "num" version = "0.4.0" @@ -1063,18 +1101,18 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790" dependencies = [ "num-traits", ] [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -1082,9 +1120,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", @@ -1104,18 +1142,19 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -1123,11 +1162,11 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" dependencies = [ - "parking_lot", + "parking_lot_core", ] [[package]] @@ -1136,12 +1175,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "opentaws" version = "0.1.0" @@ -1156,9 +1189,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ "num-traits", ] @@ -1169,29 +1202,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] @@ -1229,9 +1250,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -1282,9 +1303,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro-error" @@ -1312,32 +1333,31 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -1359,15 +1379,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "rand_pcg" version = "0.3.1" @@ -1379,9 +1390,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -1391,31 +1402,30 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -1430,9 +1440,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "ring" @@ -1451,9 +1461,9 @@ dependencies = [ [[package]] name = "ringbuffer" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dfeba9c94fdc308dcfe165efa6855c698f317484b736605ff859c5fa81d992" +checksum = "b30a00730a27595dcf899dce512aa031dd650f86aafcb132fd8dd9f409b369d0" dependencies = [ "array-init", ] @@ -1469,9 +1479,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.2" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" dependencies = [ "log", "ring", @@ -1481,9 +1491,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "same-file" @@ -1524,15 +1534,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] @@ -1558,9 +1568,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -1569,33 +1579,31 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.72" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "itoa", + "itoa 1.0.2", "ryu", "serde", ] [[package]] name = "sha-1" -version = "0.9.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", "digest", - "opaque-debug", ] [[package]] name = "signal-hook" -version = "0.3.10" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ "libc", "signal-hook-registry", @@ -1612,15 +1620,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "smol" @@ -1642,9 +1650,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", "winapi", @@ -1664,9 +1672,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", @@ -1688,13 +1696,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.82" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1749,18 +1757,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -1769,9 +1777,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ "once_cell", ] @@ -1788,9 +1796,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -1803,9 +1811,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tungstenite" -version = "0.16.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" +checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5" dependencies = [ "base64", "byteorder", @@ -1833,15 +1841,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "uneval" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18af63a2eefd8deddc36dd58844ee014aca201861e8bacf8da916369df78d4da" +checksum = "63cc5d2fd8648d7e2be86098f60c9ece7045cc710b3c1e226910e2f37d11dc73" dependencies = [ "serde", "thiserror", @@ -1849,9 +1857,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] name = "unicode-normalization" @@ -1864,9 +1878,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" @@ -1874,12 +1888,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "untrusted" version = "0.7.1" @@ -1888,9 +1896,8 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "uom" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ee6bfd0a27bf614353809a035cf6880b74239ec6c5e39a7b2860ca16809137" +version = "0.32.0" +source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#c5f2ba838907ce357859aacc1b628145d29b1e68" dependencies = [ "num-traits", "serde", @@ -1899,12 +1906,13 @@ dependencies = [ [[package]] name = "ureq" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5c448dcb78ec38c7d59ec61f87f70a98ea19171e06c139357e012ee226fec90" +checksum = "9399fa2f927a3d327187cbd201480cee55bee6ac5d3c77dd27f0c6814cff16d5" dependencies = [ "base64", "chunked_transfer", + "flate2", "log", "once_cell", "rustls", @@ -1933,9 +1941,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "value-bag" -version = "1.0.0-alpha.8" +version = "1.0.0-alpha.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" dependencies = [ "ctor", "version_check", @@ -1949,9 +1957,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" @@ -1978,9 +1986,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1988,9 +1996,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", @@ -2003,9 +2011,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" dependencies = [ "cfg-if", "js-sys", @@ -2015,9 +2023,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2025,9 +2033,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -2038,15 +2046,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -2064,9 +2072,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.1" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c475786c6f47219345717a043a37ec04cb4bc185e28853adcc4fa0a947eba630" +checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" dependencies = [ "webpki", ] @@ -2110,3 +2118,46 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml index 7145667..e7bdac7 100644 --- a/aviation_database/Cargo.toml +++ b/aviation_database/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] ordered-float = { version = "2.0", default-features = false } -uom = "0.31" +uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } kd_tree = { path = "../kd_tree" } @@ -21,6 +21,6 @@ regex = "1.5" serde = {version = "1.0", features = ["derive"]} serde_json = "1.0" uneval = "0.2" -uom = "0.31" +uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } ureq = "2" kd_tree_sort = { path = "../kd_tree_sort" } diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 4d4168f..c97c4e1 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -28,7 +28,9 @@ use-serde = ["uom/use_serde"] [dependencies] aviation_database = { path = "../aviation_database"} lazy_static = { version = "1", features = [ "spin_no_std" ] } -uom = { version = "0", default-features = false, features = [ "f64", "si" ] } + +# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands +uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } ringbuffer = "0.8" serde = { version = "1.0", default-features = false, features = [ "derive" ] } serde_arrays = "0.1.0" # Serde const generic "workaround" diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index ce4448f..f52a44b 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -25,7 +25,9 @@ maintenance = { status = "actively-developed" } opentaws = { path = "../opentaws" } aviation_database = { path = "../aviation_database" } -uom = { version = "0", default-features = false, features = [ "f64", "si" ] } + +# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands +uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } casey = "0.3" serde = { version = "1.0", default-features = false, features = [ "derive" ] } From 0024ceee43ec78f52c00cebd1a69cd4f518f0881 Mon Sep 17 00:00:00 2001 From: Wanja Zaeske Date: Thu, 9 Jun 2022 15:21:11 +0200 Subject: [PATCH 16/73] update deps and flake.nix --- Cargo.lock | 2 +- flake.lock | 132 ++++++++++++++++++++++------------------------------- flake.nix | 82 ++++++++++++++++++--------------- 3 files changed, 100 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4fd4d2..f932de8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1897,7 +1897,7 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "uom" version = "0.32.0" -source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#c5f2ba838907ce357859aacc1b628145d29b1e68" +source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#f82bc456aa319892f4edad5d555a16fa7e35e6db" dependencies = [ "num-traits", "serde", diff --git a/flake.lock b/flake.lock index 74a0d60..55fba69 100644 --- a/flake.lock +++ b/flake.lock @@ -1,121 +1,97 @@ { "nodes": { - "flake-utils": { + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, "locked": { - "lastModified": 1614513358, - "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", - "type": "github" + "lastModified": 1654756015, + "narHash": "sha256-yTDkAPSUjcy8ADa6U9gP7IAVaZpEvtQt+BGHQ0v4KMA=", + "ref": "main", + "rev": "fcf7d9029dab1c4a13aaee009feba7658f415add", + "revCount": 1062, + "type": "git", + "url": "https://github.com/nix-community/fenix.git" }, "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" + "ref": "main", + "type": "git", + "url": "https://github.com/nix-community/fenix.git" } }, "naersk": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1623927034, - "narHash": "sha256-sGxlmfp5eXL5sAMNqHSb04Zq6gPl+JeltIZ226OYN0w=", - "owner": "nmattia", - "repo": "naersk", - "rev": "e09c320446c5c2516d430803f7b19f5833781337", - "type": "github" + "lastModified": 1654608517, + "narHash": "sha256-KIxHjDDJYhoiLanLjpeAk5AuZsfip8M62JhkuloEGb0=", + "ref": "master", + "rev": "14997a79cd78fe34ad6390f18a327ee0593e5eec", + "revCount": 300, + "type": "git", + "url": "https://github.com/nix-community/naersk.git" }, "original": { - "owner": "nmattia", - "repo": "naersk", - "type": "github" + "type": "git", + "url": "https://github.com/nix-community/naersk.git" } }, "nixpkgs": { "locked": { - "lastModified": 1627561173, - "narHash": "sha256-Y5ihBYW1UpyXVz1T14MTjDlg9gkS480Kz9jSCq3WqbI=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "4bdce59e5451d8716cfe3e684f4dc181b1b2faff", - "type": "github" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1627561173, - "narHash": "sha256-Y5ihBYW1UpyXVz1T14MTjDlg9gkS480Kz9jSCq3WqbI=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "4bdce59e5451d8716cfe3e684f4dc181b1b2faff", - "type": "github" + "lastModified": 0, + "narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=", + "path": "/nix/store/ny7x54058ki7k1d3ny0jx5h6kw926mxv-source", + "type": "path" }, "original": { "id": "nixpkgs", "type": "indirect" } }, - "nixpkgs_3": { - "locked": { - "lastModified": 1617325113, - "narHash": "sha256-GksR0nvGxfZ79T91UUtWjjccxazv6Yh/MvEJ82v1Xmw=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "54c1e44240d8a527a8f4892608c4bce5440c3ecb", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" - } - }, "root": { "inputs": { + "fenix": "fenix", "naersk": "naersk", - "nixpkgs": "nixpkgs_2", - "rust-overlay": "rust-overlay", + "nixpkgs": "nixpkgs", "utils": "utils" } }, - "rust-overlay": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs_3" - }, + "rust-analyzer-src": { + "flake": false, "locked": { - "lastModified": 1627524933, - "narHash": "sha256-7qCl4c+vZ+yJhdiOE/yA3rS5wHcuTWIr/opACzrF7tQ=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "b5ee17f42141064953982ece1944ee29b4f88107", + "lastModified": 1654700117, + "narHash": "sha256-x3rF4IMwZUYnwF3JUnJvtIJmixrYkrl74K9EjhJMSr8=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "79a4a464b07d626de17bd4b5f2382b5634644f7d", "type": "github" }, "original": { - "owner": "oxalica", - "repo": "rust-overlay", + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", "type": "github" } }, "utils": { "locked": { - "lastModified": 1623875721, - "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", - "type": "github" + "lastModified": 1653893745, + "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=", + "ref": "master", + "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1", + "revCount": 58, + "type": "git", + "url": "https://github.com/numtide/flake-utils.git" }, "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" + "type": "git", + "url": "https://github.com/numtide/flake-utils.git" } } }, diff --git a/flake.nix b/flake.nix index 074dab0..f7b0001 100644 --- a/flake.nix +++ b/flake.nix @@ -1,46 +1,54 @@ { inputs = { - utils.url = "github:numtide/flake-utils"; - naersk.url = "github:nmattia/naersk"; - rust-overlay.url = "github:oxalica/rust-overlay"; + utils.url = "git+https://github.com/numtide/flake-utils.git"; + fenix = { + url = "git+https://github.com/nix-community/fenix.git?ref=main"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + naersk = { + url = "git+https://github.com/nix-community/naersk.git"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { self, nixpkgs, utils, naersk, rust-overlay }: + outputs = { self, nixpkgs, utils, fenix, naersk }: utils.lib.eachSystem [ "aarch64-linux" "i686-linux" "x86_64-linux" ] - (system: - let - overlays = [ (import rust-overlay) ]; - pkgs = import nixpkgs { inherit system overlays; }; - naersk-lib = naersk.lib."${system}"; - in rec { - packages.opentaws = naersk-lib.buildPackage { - pname = "opentaws"; - root = ./.; - doCheck = true; - doDoc = true; - copyLibs = true; - doDocFail = true; - copyTarget = true; - }; - defaultPackage = packages.opentaws; + (system: + let + pkgs = import nixpkgs { inherit system; }; + rust-toolchain = with fenix.packages.${system}; combine [ + rust-analyzer + stable.cargo + stable.rustc + stable.rustfmt + ]; + naersk-lib = (naersk.lib."${system}".override { + cargo = rust-toolchain; + rustc = rust-toolchain; + }); + in + rec { + packages.opentaws = naersk-lib.buildPackage { + pname = "opentaws"; + root = ./.; + doCheck = true; + doDoc = true; + copyLibs = true; + doDocFail = true; + copyTarget = true; + }; + defaultPackage = packages.opentaws; - devShell = pkgs.mkShell { - nativeBuildInputs = with pkgs; - [ - (rust-bin.stable.latest.default.override { - extensions = - [ "rust-src" "clippy" "rustfmt" "llvm-tools-preview" ]; - targets = [ "arm-unknown-linux-gnueabihf" ]; - }) - ]; - }; + devShell = pkgs.mkShell { + inputsFrom = [ packages.opentaws ]; + }; - # Hail to the Hydra - hydraJobs.opentaws."system" = packages.opentaws // { - meta = { - timeout = 86400; - maxSilent = 36000; + # Hail to the Hydra + hydraJobs.opentaws."system" = packages.opentaws // { + meta = { + timeout = 86400; + maxSilent = 36000; + }; }; - }; - }); + }); } From 768c64b43fee11ab0b32552d3910f22dfffe7be1 Mon Sep 17 00:00:00 2001 From: Wanja Zaeske Date: Thu, 9 Jun 2022 16:04:15 +0200 Subject: [PATCH 17/73] more updating + some test case fixing --- Cargo.lock | 252 ++++++++++++++++++++++++++--------- aviation_database/Cargo.toml | 2 +- aviation_database/src/lib.rs | 23 +++- opentaws/Cargo.toml | 2 +- taws_minimal/Cargo.toml | 6 +- 5 files changed, 211 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f932de8..eb66fe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.57" @@ -308,6 +299,12 @@ version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "byteorder" version = "1.4.3" @@ -368,13 +365,48 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term", - "atty", "bitflags", - "strsim", "textwrap 0.11.0", "unicode-width", - "vec_map", +] + +[[package]] +name = "clap" +version = "3.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "lazy_static", + "strsim", + "termcolor", + "textwrap 0.15.0", +] + +[[package]] +name = "clap_derive" +version = "3.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -427,7 +459,7 @@ checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" dependencies = [ "atty", "cast", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -544,40 +576,57 @@ dependencies = [ [[package]] name = "cucumber" -version = "0.10.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab886787f3c659f408c5fe0a9d7bd1d831ed324fcb55aa89bf339fee8b027b6" +checksum = "399fa7fc41ab7163fc49d5c2613b582b04bbf2d5342fcb1946fc1efd5b71193c" dependencies = [ "async-trait", "atty", + "clap 3.1.18", "console", "cucumber-codegen", + "cucumber-expressions", "derive_more", "either", "futures", - "gherkin_rust", + "gherkin", "globwalk", "inventory", "itertools", "linked-hash-map", "once_cell", "regex", - "sealed", - "structopt", + "sealed 0.4.0", ] [[package]] name = "cucumber-codegen" -version = "0.10.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9313bba9a820772969ee89f947d91e867c3e37ce6694583ac73466977a9a9f1f" +checksum = "6a6f939adacd640286fb794ec392c068367991795db4c2c9112b748fb4fbf04f" dependencies = [ + "cucumber-expressions", "inflections", "itertools", "proc-macro2", "quote", "regex", "syn", + "synthez", +] + +[[package]] +name = "cucumber-expressions" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40d2fdf5e1bb4ae7e6b25c97bf9b9d249a02243fc0fbd91075592b5f00a3bc1" +dependencies = [ + "derive_more", + "either", + "nom", + "nom_locate", + "regex", + "regex-syntax", ] [[package]] @@ -791,12 +840,12 @@ dependencies = [ ] [[package]] -name = "gherkin_rust" -version = "0.10.1" +name = "gherkin" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ff71b5e012707c7c18bdb710e07736898aba0451f6ffbd435c892dd993053c" +checksum = "98ab17bb865b7c4fbca5133801229aeb127e254a47c29fd26968195fce9458ab" dependencies = [ - "heck", + "heck 0.3.3", "peg", "quote", "serde", @@ -860,6 +909,12 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" version = "0.3.3" @@ -869,6 +924,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -924,6 +985,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "inflections" version = "1.1.1" @@ -941,24 +1012,12 @@ dependencies = [ [[package]] name = "inventory" -version = "0.1.11" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb5160c60ba1e809707918ee329adb99d222888155835c6feedba19f6c3fd4" +checksum = "84344c6e0b90a9e2b6f3f9abe5cc74402684e348df7b32adca28747e0cef091a" dependencies = [ "ctor", "ghost", - "inventory-impl", -] - -[[package]] -name = "inventory-impl" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548" -dependencies = [ - "proc-macro2", - "quote", - "syn", ] [[package]] @@ -1077,6 +1136,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -1086,6 +1151,27 @@ dependencies = [ "adler", ] +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom_locate" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37794436ca3029a3089e0b95d42da1f0b565ad271e4d3bb4bad0c7bb70b10605" +dependencies = [ + "bytecount", + "memchr", + "nom", +] + [[package]] name = "num" version = "0.4.0" @@ -1196,6 +1282,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_str_bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" + [[package]] name = "parking" version = "2.0.0" @@ -1526,7 +1618,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "636b9882a0f4cc2039488df89a10eb4b7976d4b6c1917fc0518f3f0f5e2c72ca" dependencies = [ - "heck", + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sealed" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b5e421024b5e5edfbaa8e60ecf90bda9dbffc602dbb230e6028763f85f0c68c" +dependencies = [ + "heck 0.3.3", "proc-macro2", "quote", "syn", @@ -1666,43 +1770,52 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "structopt" -version = "0.3.26" +name = "synthez" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +checksum = "033178d0acccffc5490021657006e6a8dd586ee9dc6f7c24e7608b125e568cb1" dependencies = [ - "clap", - "lazy_static", - "structopt-derive", + "syn", + "synthez-codegen", + "synthez-core", ] [[package]] -name = "structopt-derive" -version = "0.4.18" +name = "synthez-codegen" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +checksum = "69263462a40e46960f070618e20094ce69e783a41f86e54bc75545136afd597a" dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", "syn", + "synthez-core", ] [[package]] -name = "syn" -version = "1.0.96" +name = "synthez-core" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "bb8b5a4089fe1723279f06302afda64a5dacaa11a82bcbb4d08759590d4389d9" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "sealed 0.3.0", + "syn", ] [[package]] @@ -1727,6 +1840,15 @@ dependencies = [ "uom", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.1.17" @@ -1755,6 +1877,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "thiserror" version = "1.0.31" @@ -1949,12 +2077,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml index e7bdac7..a5dff6c 100644 --- a/aviation_database/Cargo.toml +++ b/aviation_database/Cargo.toml @@ -18,7 +18,7 @@ proc-macro2 = "1.0" quote = "1.0" rayon = "1.5" regex = "1.5" -serde = {version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uneval = "0.2" uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } diff --git a/aviation_database/src/lib.rs b/aviation_database/src/lib.rs index 5d229d1..2f009ad 100644 --- a/aviation_database/src/lib.rs +++ b/aviation_database/src/lib.rs @@ -126,11 +126,26 @@ impl Position { /// panic: /// /// ``` - /// use crate::reference::PositionImpl; - /// let p1 = PositionImpl::new(54, 10, 0); - /// let p1 = PositionImpl::new(52, 8, 10); + /// use aviation_database::Position; + /// use uom::si::{ + /// f64::{Angle, Length}, + /// angle::degree, + /// length::meter, + /// }; /// - /// assert_eq!(p1.great_circle(p2), p2.great_circle(p1)); + /// let p1 = Position{ + /// lat: Angle::new::(54.0), + /// lon: Angle::new::(10.0), + /// alt: Length::new::(1000.0), + /// }; + /// let p2 = Position{ + /// lat: Angle::new::(52.0), + /// lon: Angle::new::(8.0), + /// alt: Length::new::(1000.0), + /// }; + /// + /// let distance_delta = p1.great_circle(&p2) - p2.great_circle(&p1); + /// assert!(distance_delta.abs() < Length::new::(1.0)); /// ``` #[allow(non_snake_case)] pub fn great_circle(&self, other: &Position) -> Length { diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index c97c4e1..553c97e 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -33,4 +33,4 @@ lazy_static = { version = "1", features = [ "spin_no_std" ] } uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } ringbuffer = "0.8" serde = { version = "1.0", default-features = false, features = [ "derive" ] } -serde_arrays = "0.1.0" # Serde const generic "workaround" +serde_arrays = "*" # Serde const generic "workaround" diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index f52a44b..883a8f0 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -31,18 +31,18 @@ uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", casey = "0.3" serde = { version = "1.0", default-features = false, features = [ "derive" ] } -# testing ang examples +# testing and examples arbitrary = { version = "1", features = ["derive"], optional = true } async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } async-trait = { version = "0.1", optional = true } -cucumber = { version = "0.10", optional = true } +cucumber = { version = "0", optional = true } futures = { version = "0", optional = true } lazy_static = { version = "1.4", optional = true } rand = { version = "*", optional = true } rand_pcg = { version = "*", optional = true } rayon = { version = "1.5", optional = true } serde_json = { version = "1.0", optional = true } -smol = { version = "1.0", optional = true } +smol = { version = "1", optional = true } [[test]] From 5ecc02c86cedce0b1befac949b5c034197edfd33 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 17 Aug 2022 15:50:39 +0200 Subject: [PATCH 18/73] fix: update Cargo.lock --- Cargo.lock | 364 +++++++++++++++++++++++++---------------------------- 1 file changed, 174 insertions(+), 190 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb66fe2..e75b0b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,30 +19,30 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] name = "arbitrary" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38b6b6b79f671c25e1a3e785b7b82d7562ffc9cd3efdc98627e5668a2472490" +checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60" dependencies = [ "derive_arbitrary", ] [[package]] name = "array-init" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6945cc5422176fc5e602e590c2878d2c2acd9a4fe20a4baa7c28022521698ec6" +checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596" [[package]] name = "async-channel" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" dependencies = [ "concurrent-queue", "event-listener", @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8b508d585e01084059b60f06ade4cb7415cd2e4084b71dd1cb44e7d3fb9880" +checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" dependencies = [ "async-channel", "async-executor", @@ -86,6 +86,7 @@ dependencies = [ "async-lock", "blocking", "futures-lite", + "num_cpus", "once_cell", ] @@ -147,9 +148,9 @@ dependencies = [ [[package]] name = "async-std" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-channel", "async-global-executor", @@ -164,7 +165,6 @@ dependencies = [ "kv-log-macro", "log", "memchr", - "num_cpus", "once_cell", "pin-project-lite", "pin-utils", @@ -174,15 +174,15 @@ dependencies = [ [[package]] name = "async-task" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" dependencies = [ "proc-macro2", "quote", @@ -313,9 +313,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cache-padded" @@ -334,12 +334,9 @@ dependencies = [ [[package]] name = "cast" -version = "0.2.7" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" @@ -372,16 +369,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim", "termcolor", "textwrap 0.15.0", @@ -389,9 +386,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.18" +version = "3.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -402,32 +399,31 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] name = "concurrent-queue" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" dependencies = [ "cache-padded", ] [[package]] name = "console" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" dependencies = [ "encode_unicode", "libc", "once_cell", - "regex", "terminal_size", "unicode-width", "winapi", @@ -453,9 +449,9 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", @@ -479,9 +475,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", "itertools", @@ -489,9 +485,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", @@ -499,9 +495,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -510,33 +506,33 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -566,9 +562,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" dependencies = [ "quote", "syn", @@ -582,7 +578,7 @@ checksum = "399fa7fc41ab7163fc49d5c2613b582b04bbf2d5342fcb1946fc1efd5b71193c" dependencies = [ "async-trait", "atty", - "clap 3.1.18", + "clap 3.2.17", "console", "cucumber-codegen", "cucumber-expressions", @@ -631,9 +627,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e23c06c035dac87bd802d98f368df73a7f2cb05a66ffbd1f377e821fac4af9" +checksum = "c9a577516173adb681466d517d39bd468293bc2c2a16439375ef0f35bba45f3d" dependencies = [ "proc-macro2", "quote", @@ -663,9 +659,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" [[package]] name = "encode_unicode" @@ -675,15 +671,15 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "event-listener" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -716,9 +712,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" dependencies = [ "futures-channel", "futures-core", @@ -731,9 +727,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" dependencies = [ "futures-core", "futures-sink", @@ -741,15 +737,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" dependencies = [ "futures-core", "futures-task", @@ -758,9 +754,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" [[package]] name = "futures-lite" @@ -779,9 +775,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" dependencies = [ "proc-macro2", "quote", @@ -790,21 +786,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ "futures-channel", "futures-core", @@ -820,9 +816,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -830,9 +826,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", @@ -858,9 +854,9 @@ dependencies = [ [[package]] name = "ghost" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c813ffb63e8fd3df6f1ac3cc1ea392c7612ac2de4d0b44dcbfe03e5c4bf94a" +checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a" dependencies = [ "proc-macro2", "quote", @@ -869,9 +865,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" dependencies = [ "aho-corasick", "bstr", @@ -911,9 +907,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -947,7 +943,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa 1.0.3", ] [[package]] @@ -987,9 +983,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", @@ -1037,15 +1033,15 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -1089,21 +1085,21 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.126" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libm" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" +checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "log" @@ -1187,9 +1183,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790" +checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" dependencies = [ "num-traits", ] @@ -1217,9 +1213,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", "num-integer", @@ -1248,9 +1244,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" dependencies = [ "parking_lot_core", ] @@ -1284,9 +1280,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "parking" @@ -1354,9 +1350,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f" dependencies = [ "num-traits", "plotters-backend", @@ -1367,15 +1363,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" dependencies = [ "plotters-backend", ] @@ -1425,18 +1421,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1506,18 +1502,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -1532,9 +1528,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "ring" @@ -1560,15 +1556,6 @@ dependencies = [ "array-init", ] -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustls" version = "0.20.6" @@ -1583,9 +1570,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -1636,17 +1623,11 @@ dependencies = [ "syn", ] -[[package]] -name = "semver" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" - [[package]] name = "serde" -version = "1.0.137" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" dependencies = [ "serde_derive", ] @@ -1672,9 +1653,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" dependencies = [ "proc-macro2", "quote", @@ -1683,11 +1664,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.3", "ryu", "serde", ] @@ -1724,15 +1705,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "smol" @@ -1776,9 +1760,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.96" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -1885,18 +1869,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -1939,9 +1923,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tungstenite" -version = "0.17.2" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ "base64", "byteorder", @@ -1991,15 +1975,15 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" dependencies = [ "tinyvec", ] @@ -2025,7 +2009,7 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "uom" version = "0.32.0" -source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#f82bc456aa319892f4edad5d555a16fa7e35e6db" +source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#d87446532affa55eecb697a227fcf09d0b02f55b" dependencies = [ "num-traits", "serde", @@ -2034,9 +2018,9 @@ dependencies = [ [[package]] name = "ureq" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9399fa2f927a3d327187cbd201480cee55bee6ac5d3c77dd27f0c6814cff16d5" +checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" dependencies = [ "base64", "chunked_transfer", @@ -2102,15 +2086,15 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2118,13 +2102,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -2133,9 +2117,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if", "js-sys", @@ -2145,9 +2129,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2155,9 +2139,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -2168,15 +2152,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -2194,9 +2178,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" dependencies = [ "webpki", ] From acfc1f9fc8ba10676f62cde029548d2def5820ee Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 17 Aug 2022 16:07:35 +0200 Subject: [PATCH 19/73] fix(opentaws): Impl default trait for TawsConfig --- opentaws/src/types.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/opentaws/src/types.rs b/opentaws/src/types.rs index 90b9f57..7c10399 100644 --- a/opentaws/src/types.rs +++ b/opentaws/src/types.rs @@ -1,5 +1,6 @@ use core::{ fmt, + iter::Empty, ops::{Add, Rem}, }; @@ -7,6 +8,7 @@ use uom::{ fmt::DisplayStyle::Abbreviation, si::f64::*, si::{ + acceleration::foot_per_second_squared, angle::{degree, revolution}, length::foot, time::second, @@ -14,7 +16,7 @@ use uom::{ }, }; -use aviation_database::{AirportDatabase, Position, Runway}; +use aviation_database::{reference::AirportDatabaseImpl, AirportDatabase, Position, Runway}; /// Represents the current state of an aircraft #[derive(Clone, Debug, Default)] @@ -169,17 +171,16 @@ impl fmt::Display for AircraftState { } } -/* impl<'a> Default for TawsConfig<'a> { fn default() -> Self { + static AIRPORT_DATABASE: AirportDatabaseImpl = AirportDatabaseImpl {}; Self { - terrain_server: &'static AirportDatabaseImpl, + terrain_server: &AIRPORT_DATABASE, max_climbrate: Velocity::new::(700.0), max_climbrate_change: Acceleration::new::(100.0), } } } - */ #[cfg(test)] mod test { From 53075b3a9578903a780719fefb5229006912975c Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 23 Aug 2022 14:50:51 +0200 Subject: [PATCH 20/73] fix(PDA): invalid envelope --- opentaws/src/alerts/pda.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentaws/src/alerts/pda.rs b/opentaws/src/alerts/pda.rs index 41912b8..8d64f66 100644 --- a/opentaws/src/alerts/pda.rs +++ b/opentaws/src/alerts/pda.rs @@ -52,7 +52,7 @@ lazy_static::lazy_static! { /// Y-Axis is Height above Terrain in foot static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new([ (0.9, 5.0), - (0.9, 85.0), + (0.90001, 85.0), (1.8, 155.0), (2.3, 175.0), (2.4, 175.0), From 75e704e0327fee3c0e072cfb8502e72b641445be Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 23 Aug 2022 14:53:33 +0200 Subject: [PATCH 21/73] Refactor cucumber tests --- Cargo.lock | 1 + taws_minimal/Cargo.toml | 31 +- taws_minimal/tests/cucumber.rs | 374 +++++++----------- taws_minimal/tests/util/aircraft_state.rs | 57 +++ .../aircraft_state.rs} | 115 +----- .../util/constraints/airport_database.rs | 8 + .../tests/util/constraints/constraint.rs | 146 +++++++ taws_minimal/tests/util/constraints/mod.rs | 9 + .../tests/util/constraints/press_mould.rs | 86 ++++ taws_minimal/tests/util/mod.rs | 218 +--------- taws_minimal/tests/util/parameters.rs | 168 ++++++++ taws_minimal/tests/util/world.rs | 49 +++ 12 files changed, 700 insertions(+), 562 deletions(-) create mode 100644 taws_minimal/tests/util/aircraft_state.rs rename taws_minimal/tests/util/{constraint.rs => constraints/aircraft_state.rs} (67%) create mode 100644 taws_minimal/tests/util/constraints/airport_database.rs create mode 100644 taws_minimal/tests/util/constraints/constraint.rs create mode 100644 taws_minimal/tests/util/constraints/mod.rs create mode 100644 taws_minimal/tests/util/constraints/press_mould.rs create mode 100644 taws_minimal/tests/util/parameters.rs create mode 100644 taws_minimal/tests/util/world.rs diff --git a/Cargo.lock b/Cargo.lock index e75b0b0..883585d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1818,6 +1818,7 @@ dependencies = [ "rand", "rand_pcg", "rayon", + "regex", "serde", "serde_json", "smol", diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index 883a8f0..812cf61 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -5,7 +5,7 @@ authors = [ "Wanja Zaeske ", "Janick Beck ", "Umut Durak ", - ] +] edition = "2018" license = "MIT OR Apache-2.0" description = "A minimal implementation of openTAWS" @@ -27,15 +27,21 @@ aviation_database = { path = "../aviation_database" } # TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands -uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } +uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ + "f64", + "si", + "libm", +] } casey = "0.3" -serde = { version = "1.0", default-features = false, features = [ "derive" ] } +serde = { version = "1.0", default-features = false, features = ["derive"] } # testing and examples arbitrary = { version = "1", features = ["derive"], optional = true } -async-tungstenite = { version = "*", features = [ "async-std-runtime" ], optional = true } +async-tungstenite = { version = "*", features = [ + "async-std-runtime", +], optional = true } async-trait = { version = "0.1", optional = true } -cucumber = { version = "0", optional = true } +cucumber = { version = "0", optional = true } futures = { version = "0", optional = true } lazy_static = { version = "1.4", optional = true } rand = { version = "*", optional = true } @@ -43,25 +49,26 @@ rand_pcg = { version = "*", optional = true } rayon = { version = "1.5", optional = true } serde_json = { version = "1.0", optional = true } smol = { version = "1", optional = true } +regex = "1.6.0" [[test]] name = "cucumber" harness = false # Allows Cucumber to print output instead of libtest path = "tests/cucumber.rs" -required-features = [ - "arbitrary", - "async-trait", - "cucumber", +required-features = [ + "arbitrary", + "async-trait", + "cucumber", "futures", "lazy_static", - "rand", + "rand", "rand_pcg", "rayon", "serde_json", - "smol" + "smol", ] [[example]] name = "flightgear" -required-features = [ "async-tungstenite", "futures", "serde_json", "smol" ] +required-features = ["async-tungstenite", "futures", "serde_json", "smol"] diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index d917c33..297f88b 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -1,17 +1,15 @@ -use std::cmp::PartialEq; -use std::convert::Infallible; - -use uom::si::{f64::*, length::foot, velocity::foot_per_minute}; +//mod constraints; +mod util; -use async_trait::async_trait; use cucumber::{given, then, when, WorldInit}; -use opentaws::prelude::*; -use taws_minimal::MinimalTaws; -mod util; -use util::*; - -use util::constraint::*; +use opentaws::prelude::*; +use uom::si::f64::{Length, Velocity}; +use uom::si::{length, velocity}; +use util::aircraft_state::AircraftStateGenerator; +use util::constraints::Constraint; +use util::parameters::*; +use util::world::MyWorld; fn main() { smol::block_on(MyWorld::run("features")); @@ -21,280 +19,204 @@ fn main() { // TODO allow for statefull tests // TODO evaluate merge possibilities re parser functions for similar sentences -#[derive(WorldInit)] -pub struct MyWorld { - taws: MinimalTaws<'static>, - constraints: Vec, - test_length: usize, - last_step_type: StepType, - phase: usize, -} +#[given(expr = "the plane {maybe} flying")] +fn given_flying(_world: &mut MyWorld, _maybe: MaybeParameter) {} -//TODO use cucumber rs StepType enum -#[derive(PartialEq)] -pub enum StepType { - Given, - When, - Then, -} - -#[given("the plane is flying")] -fn is_flying(_world: &mut MyWorld) {} - -#[given(regex = r#"^(.+) is ?(not)? armed$"#)] -fn is_armed(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { - if maybe_not == "not" { - world.taws.disarm(alert.into()); - } else { - world.taws.arm(alert.into()); +#[given(expr = "{alert} {maybe} armed")] +fn given_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { + let alert: Alert = alert.into(); + match maybe.into() { + true => world.taws.arm(alert), + false => world.taws.disarm(alert), } } -#[given(regex = "^(.+) is ?(not)? inhibited$")] -fn is_inhibited(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { - if maybe_not == "not" { - world.taws.uninhibit(alert.into()); - } else { - world.taws.inhibit(alert.into()); +#[given(expr = "{alert} {maybe} inhibited")] +fn given_alert_inhibited(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { + let alert: Alert = alert.into(); + match maybe.into() { + true => world.taws.inhibit(alert), + false => world.taws.uninhibit(alert), } } -#[given(regex = r"^steep approach is ?(not)? selected$")] -fn steep_approach(world: &mut MyWorld, maybe_not: String) { - world.update_phase(StepType::Given); - if maybe_not == "not" { - world.constraints[world.phase].add_steep_approach_constraint(false) - } else { - world.constraints[world.phase].add_steep_approach_constraint(true) - } +#[given(expr = "a {alert} {alert_level} alert {maybe} active")] +fn given_alert_level_active( + _world: &mut MyWorld, + _alert: AlertParameter, + _level: AlertLevelParameter, + _maybe: MaybeParameter, +) { + todo!() } -#[given(regex = r"^take-off is ?(not)? selected$")] -fn take_of(world: &mut MyWorld, maybe_not: String) { - world.update_phase(StepType::Given); - if maybe_not == "not" { - world.constraints[world.phase].add_take_off_constraint(false) - } else { - world.constraints[world.phase].add_take_off_constraint(true) - } +#[given(expr = "steep approach {maybe} selected")] +fn given_steep_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { + world.constraints[world.phase].add_steep_approach_constraint(maybe.into()); } -#[given(regex = r"^go around is ?(not)? selected$")] -fn go_around(world: &mut MyWorld, maybe_not: String) { - world.update_phase(StepType::Given); - if maybe_not == "not" { - world.constraints[world.phase].add_go_around_constraint(false) - } else { - world.constraints[world.phase].add_go_around_constraint(true) - } +#[given(expr = "non-precision approach {maybe} selected")] +fn given_precision_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { + let maybe: bool = maybe.into(); + world.constraints[world.phase].add_precision_approach_constraint(!maybe); } -#[given(regex = r"^non-precision approach is ?(not)? selected$")] -fn precision_approach(world: &mut MyWorld, maybe_not: String) { - world.update_phase(StepType::Given); +#[given(expr = "take-off {maybe} selected")] +fn given_take_off(world: &mut MyWorld, maybe: MaybeParameter) { + world.constraints[world.phase].add_take_off_constraint(maybe.into()); +} - // double negation: non-precision is not selected - if maybe_not == "not" { - world.constraints[world.phase].add_precision_approach_constraint(true); - } else { - world.constraints[world.phase].add_precision_approach_constraint(false); - } +#[given(expr = "go around {maybe} selected")] +fn given_go_around(world: &mut MyWorld, maybe: MaybeParameter) { + world.constraints[world.phase].add_go_around_constraint(maybe.into()); } -#[then(regex = r"^(.+) shall ?(not)? be armed$")] -fn shall_be_armed(world: &mut MyWorld, alert: AlertWrapper, maybe_not: String) { - assert_eq!(world.taws.is_armed(alert.into()), !maybe_not.eq("not")); +#[given(expr = "the height above terrain is {constraint} foot")] +#[when(expr = "the height above terrain is {constraint} foot")] +fn given_height_above_terrain(world: &mut MyWorld, height_above_terrain: ConstraintParameter) { + let height_above_terrain: Constraint = height_above_terrain.into(); + + let unit = Length::new::(1.0); + let height_above_terrain = match height_above_terrain { + Constraint::AtLeast(p, a) => Constraint::AtLeast(p, a * unit), + Constraint::AtMost(p, a) => Constraint::AtMost(p, a * unit), + Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), + Constraint::InRange(p, a, b) => Constraint::InRange(p, a * unit, b * unit), + Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, a * unit, b * unit), + }; + + //let height_above_terrain = height_above_terrain * Length::new::(1.0); + + world.constraints[world.phase].add_altitude_ground_constraint(height_above_terrain); } -#[when(regex = r"^the rate of descent is at (most|least) (\d+) feet per minute$")] -fn rate_of_descent(world: &mut MyWorld, most_or_least: String, rod: f64) { - world.update_phase(StepType::When); - - let rod = Velocity::new::(rod); - // most and least are swapped here, as aircraft_state stores rate of climb, while - // the sentence give rate of descent - // TODO validate that this is a safe assumption? - match most_or_least.as_str() { - "most" => { - world.constraints[world.phase] - .add_climb_rate_constraint(Constraint::AtLeast(world.phase, -rod)); - //world.add_mould(move |a| bouncer.at_least(&mut a.climb_rate, -rod)); - } - "least" => { - world.constraints[world.phase] - .add_climb_rate_constraint(Constraint::AtMost(world.phase, -rod)); - //world.add_mould(move |a| bouncer.at_most(&mut a.climb_rate, -rod)); - } - _ => { - panic!("unable to parse this sentence"); - } - } +#[when(expr = "the rate of descent is {constraint} feet per minute")] +fn when_rate_of_descent(world: &mut MyWorld, rate_of_descent: ConstraintParameter) { + let rate_of_descent: Constraint = rate_of_descent.into(); + + let unit = Velocity::new::(-1.0); + let climb_rate = match rate_of_descent { + Constraint::AtLeast(p, a) => Constraint::AtMost(p, a * unit), + Constraint::AtMost(p, a) => Constraint::AtLeast(p, a * unit), + Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), + Constraint::InRange(p, a, b) => Constraint::InRange(p, b * unit, a * unit), + Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, b * unit, a * unit), + }; + + world.constraints[world.phase].add_climb_rate_constraint(climb_rate); } -#[when(regex = r"^the height above terrain is ?(not)? between (\d+) and (\d+) feet$")] -fn height_above_terrain(world: &mut MyWorld, maybe_not: String, lower: f64, upper: f64) { - world.update_phase(StepType::When); - - let height_at_least = Length::new::(lower); - let height_at_most = Length::new::(upper); - - if maybe_not == "not" { - world.constraints[world.phase].add_altitude_ground_constraint(Constraint::NotInRange( - world.phase, - height_at_least, - height_at_most, - )); - } else { - world.constraints[world.phase].add_altitude_ground_constraint(Constraint::InRange( - world.phase, - height_at_least, - height_at_most, - )); - // TODO altitude or altitude_ground - } +#[when(expr = "the height above terrain is {constraint} feet")] +fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: ConstraintParameter) { + let height_above_ground: Constraint = height_above_ground.into(); + + let unit = Length::new::(1.0); + let height_above_ground = match height_above_ground { + Constraint::AtLeast(p, a) => Constraint::AtLeast(p, a * unit), + Constraint::AtMost(p, a) => Constraint::AtMost(p, a * unit), + Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), + Constraint::InRange(p, a, b) => Constraint::InRange(p, a * unit, b * unit), + Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, a * unit, b * unit), + }; + + world.constraints[world.phase].add_altitude_ground_constraint(height_above_ground); } -#[when( - regex = r"^the distance to the nearest airport is ?(not)? between ([0-9]+\.?[0-9]*) and ([0-9]+\.?[0-9]*) NM" -)] -fn distance_to_airport(world: &mut MyWorld, maybe_not: String, lower: f64, upper: f64) { - world.update_phase(StepType::When); +#[given(expr = "the plane is {constraint} NM of an airport")] +#[when(expr = "the distance to the nearest airport is {constraint} NM")] +fn when_distance_to_airport(_world: &mut MyWorld, _distance: ConstraintParameter) { todo!(); - let height_at_least = Length::new::(lower); - let height_at_most = Length::new::(upper); - - if maybe_not == "not" { - } else { - } } -#[given(regex = r"^the height above terrain is at (most|least) (\d+) foot$")] -fn height_above_terrain_2(world: &mut MyWorld, greater_or_less: String, height: f64) { - todo!("Merge with previous function"); +#[when(expr = "a failure is detected by the continuos monitoring")] +#[when(expr = "the initiated self-test detects a failure")] +fn when_failure_detected(world: &mut MyWorld) { + todo!(); } -#[given(regex = r"^the nearest runway elevation is at (most|least) (\d+) foot$")] -fn height_above_runway(world: &mut MyWorld, greater_or_less: String, height: f64) { - todo!("Merge with previous function"); +#[given(expr = "the self-test is initiated")] +#[when(expr = "the self-test is initiated")] +fn when_self_test_initiated(_world: &mut MyWorld) { + todo!(); } -#[given(regex = r"^the plane is ?(not)? within ([0-9]+\.?[0-9]*) NM of an airport")] -fn distance_to_airport_2(world: &mut MyWorld, maybe_not: String, distance: f64) { - todo!("Merge with previous function"); +#[when(expr = "the rate of input data reduces or stagnates")] +fn when_data_rate_reduces(_world: &mut MyWorld) { + todo!(); } -#[then(regex = "^a (.*) alert is not emitted at all$")] -fn is_not_emitted(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper) { - world.update_phase(StepType::Then); - let (alert, level) = alert_and_level.into(); +#[then(expr = "{alert} {maybe} be armed")] +fn then_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { + assert_eq!(world.taws.is_armed(alert.into()), maybe.into()) +} - let aircraft_states = - AircraftStateGenerator::default().take(world.test_length * world.constraints.len()); +#[then(expr = "a {alert} {alert_level} alert {maybe} emitted( at all)")] +fn then_alert_emitted( + world: &mut MyWorld, + alert: AlertParameter, + level: AlertLevelParameter, + should_emit: MaybeParameter, +) { + let alert: Alert = alert.into(); + let level: AlertLevel = level.into(); + let should_emit: bool = should_emit.into(); let n_constraints = world.constraints.len(); + let aircraft_states = AircraftStateGenerator::default().take(world.test_length * n_constraints); + for (c, mut frame) in aircraft_states .enumerate() .map(|(c, f)| (c % n_constraints, f)) { world.constraints[c].apply_to(&mut frame); - let alert_state = world.taws.process(&mut frame); + let alert_state = world.taws.process(&frame); + let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); + //println!("{:#?}", alert_state); + assert_eq!(emitted, should_emit); + //alert_state.iter().filter(|(a, l)| a == alert). // Make sure we are in the last phase of this scenario with "c + 1 == world.constraints.len()" - if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { + /*if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { panic!( "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", frame, alert_state ); - } + }*/ } } -#[then(regex = r"^a (.*) alert is emitted within ([0-9]+\.?[0-9]*) seconds$")] -fn is_emitted_within(world: &mut MyWorld, alert_and_level: AlertAndLevelWrapper, _seconds: f64) { - world.update_phase(StepType::Then); - let (alert, level) = alert_and_level.into(); - - let aircraft_states = - AircraftStateGenerator::default().take(world.test_length * world.constraints.len()); +#[then(expr = "a {alert} {alert_level} alert {maybe} emitted {constraint} seconds")] +fn then_alert_emitted_within( + world: &mut MyWorld, + alert: AlertParameter, + level: AlertLevelParameter, + should_emit: MaybeParameter, + _time: ConstraintParameter, +) { + let alert: Alert = alert.into(); + let level: AlertLevel = level.into(); + let should_emit: bool = should_emit.into(); let n_constraints = world.constraints.len(); + let aircraft_states = AircraftStateGenerator::default().take(world.test_length * n_constraints); + for (c, mut frame) in aircraft_states .enumerate() .map(|(c, f)| (c % n_constraints, f)) { world.constraints[c].apply_to(&mut frame); - let alert_state = world.taws.process(&mut frame); - // TODO what about the time constraint? - // Count all alerts that are from the functionality Mode1 and are of higher or - // same priority as `level`. If the count is 0, the system did not alert - // appropriately. - if c + 1 == n_constraints - && alert_state - .iter() - .filter(|(a, l)| *a == alert && *l <= level) - .count() - == 0 - { + let alert_state = world.taws.process(&frame); + let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); + //println!("{:#?}", alert_state); + assert_eq!(emitted, should_emit); + //alert_state.iter().filter(|(a, l)| a == alert). + // Make sure we are in the last phase of this scenario with "c + 1 == world.constraints.len()" + /*if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { panic!( "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", frame, alert_state ); - } + }*/ } } - -static AIRPORT_DATABASE: ConstraintAirportDatabase = ConstraintAirportDatabase {}; - -lazy_static::lazy_static! { - static ref TAWS_CONFIG: TawsConfig<'static> = TawsConfig{ - terrain_server: &AIRPORT_DATABASE, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - }; -} - -// Brot und Butter implementations -#[async_trait(?Send)] -impl cucumber::World for MyWorld { - type Error = Infallible; - - async fn new() -> Result { - Ok(Self { - taws: MinimalTaws::new(&TAWS_CONFIG), - constraints: vec![AircraftStateConstraints::default()], - test_length: 10, // TODO Increase should we be able to reduce the nearest_airport function from the aviation database - last_step_type: StepType::Given, - phase: 0, - }) - } -} - -impl MyWorld { - // Updates the current phase based on the current StepType - pub fn update_phase(&mut self, current_type: StepType) { - if self.last_step_type != current_type { - //Only increase phase if current phase is not "Then" - // Then-Step should not enforce AirplaneStateConstraints - if current_type != StepType::Then { - self.constraints.push(self.constraints[self.phase].clone()); - self.phase += 1; - } - - if self.last_step_type == StepType::Then && current_type == StepType::When { - panic!("Multiple When/Then Pairs are not allowed") - } - - self.last_step_type = current_type; - } - } -} - -impl std::fmt::Debug for MyWorld { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("MyWorld").finish() - //todo!(); - } -} - -impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? diff --git a/taws_minimal/tests/util/aircraft_state.rs b/taws_minimal/tests/util/aircraft_state.rs new file mode 100644 index 0000000..c1176db --- /dev/null +++ b/taws_minimal/tests/util/aircraft_state.rs @@ -0,0 +1,57 @@ +use arbitrary::{Arbitrary, Unstructured}; +use opentaws::prelude::*; +use rand::RngCore; + +#[derive(Debug, Clone)] +struct AircraftStateWrapper(AircraftState); + +impl<'a> Arbitrary<'a> for AircraftStateWrapper { + fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { + Ok(AircraftStateWrapper(AircraftState { + timestamp: Time::new::(::arbitrary(u)? as f64), + altitude: Length::new::(::arbitrary(u)? as f64), + altitude_ground: Length::new::(::arbitrary(u)? as f64), + climb_rate: Velocity::new::(::arbitrary(u)? as f64), + position_lat: Angle::new::(::arbitrary(u)? as f64), + position_lon: Angle::new::(::arbitrary(u)? as f64), + speed_ground: Velocity::new::(::arbitrary(u)? as f64), + speed_air: Velocity::new::(::arbitrary(u)? as f64), + heading: Angle::new::(::arbitrary(u)? as f64), + pitch: Angle::new::(::arbitrary(u)? as f64), + roll: Angle::new::(::arbitrary(u)? as f64), + steep_approach: u.arbitrary()?, + precision_approach: u.arbitrary()?, + go_around: u.arbitrary()?, + take_off: u.arbitrary()?, + })) + } + + fn size_hint(_depth: usize) -> (usize, Option) { + (std::mem::size_of::(), None) + } +} + +// AircraftState generator +type Prng = rand_pcg::Mcg128Xsl64; +pub struct AircraftStateGenerator(pub Prng); + +impl Default for AircraftStateGenerator { + fn default() -> Self { + Self(Prng::new(0xcafef00dd15ea5e5)) + } +} + +impl Iterator for AircraftStateGenerator { + type Item = AircraftState; + + fn next(&mut self) -> Option { + let bytes_needed = AircraftStateWrapper::size_hint(0).0; + let mut buf = Vec::with_capacity(bytes_needed); + while buf.len() < bytes_needed { + buf.extend_from_slice(&self.0.next_u64().to_le_bytes()); + } + let mut u = Unstructured::new(&mut buf); + + Some(AircraftStateWrapper::arbitrary(&mut u).unwrap().0) // the unwrap is safe, we guarantee that enough bytes are available + } +} diff --git a/taws_minimal/tests/util/constraint.rs b/taws_minimal/tests/util/constraints/aircraft_state.rs similarity index 67% rename from taws_minimal/tests/util/constraint.rs rename to taws_minimal/tests/util/constraints/aircraft_state.rs index b0f8825..b28637b 100644 --- a/taws_minimal/tests/util/constraint.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state.rs @@ -1,9 +1,6 @@ -#[allow(dead_code)] -use crate::util::PressMould; -use crate::BouncingClamp; -use aviation_database::{AirportDatabase, Runway}; +use super::{constraint::Constraint, press_mould}; use opentaws::AircraftState; -use uom::si::f64::*; +use uom::si::f64::{Angle, Length, Velocity}; #[derive(Clone, Default, PartialEq)] pub struct AircraftStateConstraints { @@ -34,7 +31,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + crate::util::Abs + + press_mould::Abs + std::fmt::Debug, { let mut i = 0; @@ -60,7 +57,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + crate::util::Abs + + press_mould::Abs + std::fmt::Debug, { let mut cs = Vec::new(); @@ -130,7 +127,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + crate::util::Abs + + press_mould::Abs + std::fmt::Debug, { let merged = Self::merge(constraints); @@ -216,105 +213,3 @@ impl AircraftStateConstraints { self.take_of = c; } } - -#[derive(Clone, PartialEq, Debug)] -pub enum Constraint -where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Add - + std::ops::Rem - + std::ops::Rem - + std::ops::Sub - + std::ops::Sub - + crate::util::Abs - + std::fmt::Debug, -{ - AtLeast(usize, Q), - AtMost(usize, Q), - Equal(usize, Q), - InRange(usize, Q, Q), - NotInRange(usize, Q, Q), -} - -impl Constraint -where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Add - + std::ops::Rem - + std::ops::Rem - + std::ops::Sub - + std::ops::Sub - + crate::util::Abs - + std::fmt::Debug, -{ - pub fn phase(&self) -> usize { - match self { - Constraint::AtLeast(i, _) => *i, - Constraint::AtMost(i, _) => *i, - Constraint::Equal(i, _) => *i, - Constraint::InRange(i, _, _) => *i, - Constraint::NotInRange(i, _, _) => *i, - } - } - - pub fn apply_to(&self, quantity: &mut Q) { - let mut bouncer = BouncingClamp(); - - match self { - Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), - Constraint::AtMost(_, l) => bouncer.at_most(quantity, *l), - Constraint::Equal(_, l) => *quantity = *l, - Constraint::InRange(_, l, r) => bouncer.in_range(quantity, *l, *r), - Constraint::NotInRange(_, l, r) => bouncer.not_in_range(quantity, *l, *r), - } - } - - pub fn check(&self, to_check: Q) { - match self { - Constraint::AtLeast(_, l) => assert!( - to_check >= *l, - "Checked Number {:?} failed constraint: at least {:?}", - to_check, - l - ), - Constraint::AtMost(_, l) => assert!( - to_check <= *l, - "Checked Number {:?} failed constraint: at most {:?}", - to_check, - l - ), - Constraint::Equal(_, l) => assert_eq!( - &to_check, l, - "Checked Number {:?} failed constraint: equal to {:?}", - to_check, l - ), - Constraint::InRange(_, l, r) => assert!( - to_check >= *l && to_check <= *r, - "Checked Number {:?} failed constraint: in range {:?} - {:?}", - to_check, - l, - r - ), - Constraint::NotInRange(_, l, r) => assert!( - *l < to_check || to_check < *r, - "Checked Number {:?} failed constraint: not in range {:?} - {:?}", - to_check, - r, - l - ), - } - } -} - -#[derive(Debug, Default)] -pub struct ConstraintAirportDatabase; - -impl AirportDatabase for ConstraintAirportDatabase { - type RunwayIterator = core::iter::Empty; -} diff --git a/taws_minimal/tests/util/constraints/airport_database.rs b/taws_minimal/tests/util/constraints/airport_database.rs new file mode 100644 index 0000000..14faee0 --- /dev/null +++ b/taws_minimal/tests/util/constraints/airport_database.rs @@ -0,0 +1,8 @@ +use aviation_database::{AirportDatabase, Runway}; + +#[derive(Debug, Default)] +pub struct ConstraintAirportDatabase; + +impl AirportDatabase for ConstraintAirportDatabase { + type RunwayIterator = core::iter::Empty; +} diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs new file mode 100644 index 0000000..58ea0ba --- /dev/null +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -0,0 +1,146 @@ +use std::any::Any; + +use uom::num_traits::{Signed, Zero}; + +use super::press_mould::{self, PressMould}; + +#[derive(Clone, PartialEq, Debug)] +pub enum Constraint +where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + press_mould::Abs + + std::fmt::Debug, +{ + AtLeast(usize, Q), + AtMost(usize, Q), + Equal(usize, Q), + InRange(usize, Q, Q), + NotInRange(usize, Q, Q), +} + +impl Constraint +where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + press_mould::Abs + + std::fmt::Debug, +{ + pub fn phase(&self) -> usize { + match self { + Constraint::AtLeast(i, _) => *i, + Constraint::AtMost(i, _) => *i, + Constraint::Equal(i, _) => *i, + Constraint::InRange(i, _, _) => *i, + Constraint::NotInRange(i, _, _) => *i, + } + } + + pub fn apply_to(&self, quantity: &mut Q) { + let mut bouncer = press_mould::BouncingClamp(); + + match self { + Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), + Constraint::AtMost(_, l) => bouncer.at_most(quantity, *l), + Constraint::Equal(_, l) => *quantity = *l, + Constraint::InRange(_, l, r) => bouncer.in_range(quantity, *l, *r), + Constraint::NotInRange(_, l, r) => bouncer.not_in_range(quantity, *l, *r), + } + } + + pub fn check(&self, to_check: Q) { + match self { + Constraint::AtLeast(_, l) => assert!( + to_check >= *l, + "Checked Number {:?} failed constraint: at least {:?}", + to_check, + l + ), + Constraint::AtMost(_, l) => assert!( + to_check <= *l, + "Checked Number {:?} failed constraint: at most {:?}", + to_check, + l + ), + Constraint::Equal(_, l) => assert_eq!( + &to_check, l, + "Checked Number {:?} failed constraint: equal to {:?}", + to_check, l + ), + Constraint::InRange(_, l, r) => assert!( + to_check >= *l && to_check <= *r, + "Checked Number {:?} failed constraint: in range {:?} - {:?}", + to_check, + l, + r + ), + Constraint::NotInRange(_, l, r) => assert!( + *l < to_check || to_check < *r, + "Checked Number {:?} failed constraint: not in range {:?} - {:?}", + to_check, + r, + l + ), + } + } +} + +/*impl std::ops::Mul for Constraint +where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + press_mould::Abs + + std::fmt::Debug + + std::ops::Mul, + R: Copy + Zero + PartialOrd, + Z: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Add + + std::ops::Rem + + std::ops::Rem + + std::ops::Sub + + std::ops::Sub + + press_mould::Abs + + std::fmt::Debug, +{ + type Output = Constraint; + + fn mul(self, r: R) -> Constraint { + let zero = R::zero(); + match self { + Constraint::AtLeast(x, y) if r >= zero => Constraint::AtLeast(x, y * r), + Constraint::AtLeast(x, y) if r < zero => Constraint::AtMost(x, y * r), + Constraint::AtMost(x, y) if r >= zero => Constraint::AtMost(x, y * r), + Constraint::AtMost(x, y) if r < zero => Constraint::AtLeast(x, y * r), + Constraint::Equal(x, y) => Constraint::Equal(x, y * r), + Constraint::InRange(x, a, b) if r >= zero => Constraint::InRange(x, a * r, b * r), + Constraint::InRange(x, a, b) if r < zero => Constraint::InRange(x, b * r, a * r), + Constraint::NotInRange(x, a, b) if r >= zero => Constraint::NotInRange(x, a * r, b * r), + Constraint::NotInRange(x, a, b) if r < zero => Constraint::NotInRange(x, b * r, a * r), + _ => panic!("cannot happen"), + } + } +}*/ diff --git a/taws_minimal/tests/util/constraints/mod.rs b/taws_minimal/tests/util/constraints/mod.rs new file mode 100644 index 0000000..4e76f4e --- /dev/null +++ b/taws_minimal/tests/util/constraints/mod.rs @@ -0,0 +1,9 @@ +mod aircraft_state; +mod airport_database; +mod constraint; +mod press_mould; + +pub use aircraft_state::*; +pub use airport_database::*; +pub use constraint::*; +pub use press_mould::*; diff --git a/taws_minimal/tests/util/constraints/press_mould.rs b/taws_minimal/tests/util/constraints/press_mould.rs new file mode 100644 index 0000000..2fd1268 --- /dev/null +++ b/taws_minimal/tests/util/constraints/press_mould.rs @@ -0,0 +1,86 @@ +use std::ops::{Add, Rem, Sub}; + +use uom::num_traits::Signed; + +// for the lack of a better word +pub trait PressMould { + fn at_least(&mut self, value: &mut T, at_least: T); + fn at_most(&mut self, value: &mut T, at_most: T); + fn in_range(&mut self, value: &mut T, at_least: T, at_most: T); + fn not_in_range(&mut self, value: &mut T, range_from: T, range_to: T); +} + +// Stupid +pub struct BouncingClamp(); + +impl PressMould for BouncingClamp +where + T: Copy + + Clone + + std::fmt::Debug + + PartialOrd + + Add + + Rem + + Sub + + Abs, +{ + fn at_least(&mut self, value: &mut T, at_least: T) { + if *value < at_least { + *value = at_least + (at_least - *value) + } + assert!(*value >= at_least); + } + + fn at_most(&mut self, value: &mut T, at_most: T) { + if *value > at_most { + *value = at_most - (*value - at_most) + } + assert!(*value <= at_most); + } + + fn in_range(&mut self, value: &mut T, at_least: T, at_most: T) { + assert!(at_least <= at_most); + + if at_least == at_most { + *value = at_least; + return; + } + + let modulo = |a: T, b: T| ((a % b) + b) % b; + + let span = at_most - at_least; + let bounced = (modulo(*value + span, span + span) - span).abs(); + *value = bounced + at_least; + + assert!(at_least <= *value && *value <= at_most); + } + + fn not_in_range(&mut self, value: &mut T, at_most: T, at_least: T) { + assert!(at_most <= at_least); + if *value > at_most && *value < at_least { + *value = *value + (at_least - at_most); + } + assert!(*value < at_least || at_most < *value); + } +} + +pub trait Abs: Sized { + fn abs(self) -> Self; +} + +impl Abs for f64 { + fn abs(self) -> Self { + self.abs() + } +} + +impl Abs for uom::si::Quantity +where + D: uom::si::Dimension, + U: uom::si::Units, + V: uom::num_traits::Num + uom::Conversion + Signed, +{ + fn abs(self) -> Self { + self.abs() + } +} diff --git a/taws_minimal/tests/util/mod.rs b/taws_minimal/tests/util/mod.rs index 2e03fc7..47e8216 100644 --- a/taws_minimal/tests/util/mod.rs +++ b/taws_minimal/tests/util/mod.rs @@ -1,214 +1,4 @@ -pub mod constraint; - -use std::{ - ops::{Add, Rem, Sub}, - str::FromStr, -}; - -use arbitrary::{Arbitrary, Unstructured}; -use rand::RngCore; - -use uom::{ - num::Signed, - si::{f64::*, length::foot, time::second, velocity::foot_per_minute}, -}; - -use opentaws::prelude::*; - -#[derive(Debug, Clone)] -struct AircraftStateWrapper(AircraftState); - -impl<'a> Arbitrary<'a> for AircraftStateWrapper { - fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { - Ok(AircraftStateWrapper(AircraftState { - timestamp: Time::new::(::arbitrary(u)? as f64), - altitude: Length::new::(::arbitrary(u)? as f64), - altitude_ground: Length::new::(::arbitrary(u)? as f64), - climb_rate: Velocity::new::(::arbitrary(u)? as f64), - position_lat: Angle::new::(::arbitrary(u)? as f64), - position_lon: Angle::new::(::arbitrary(u)? as f64), - speed_ground: Velocity::new::(::arbitrary(u)? as f64), - speed_air: Velocity::new::(::arbitrary(u)? as f64), - heading: Angle::new::(::arbitrary(u)? as f64), - pitch: Angle::new::(::arbitrary(u)? as f64), - roll: Angle::new::(::arbitrary(u)? as f64), - steep_approach: u.arbitrary()?, - precision_approach: u.arbitrary()?, - go_around: u.arbitrary()?, - take_off: u.arbitrary()?, - })) - } - - fn size_hint(_depth: usize) -> (usize, Option) { - (std::mem::size_of::(), None) - } -} - -// Parser magic -pub struct AlertWrapper(Alert); -impl FromStr for AlertWrapper { - type Err = String; - fn from_str(s: &str) -> Result { - let mut input_word = s.to_lowercase(); - input_word.retain(|c| !c.is_whitespace()); - Ok(Self(match input_word.as_str() { - "ffac" => Alert::Ffac, - "flta" => Alert::Flta, - "mode1" => Alert::Mode1, - "mode2" => Alert::Mode2, - "mode3" => Alert::Mode3, - "mode4" => Alert::Mode4, - "mode5" => Alert::Mode5, - "pda" => Alert::Pda, - _ => { - panic!("unable to convert {} into a variant of `Alert`", s); - } - })) - } -} -impl Into for AlertWrapper { - fn into(self) -> Alert { - self.0 - } -} - -pub struct AlertLevelWrapper(AlertLevel); -impl FromStr for AlertLevelWrapper { - type Err = String; - fn from_str(s: &str) -> Result { - let mut input_word = s.to_string(); - input_word.retain(|c| !c.is_whitespace()); - Ok(Self(match input_word.as_str() { - "warning" => AlertLevel::Warning, - "caution" => AlertLevel::Caution, - "annunciation" => AlertLevel::Annunciation, - _ => { - panic!(r#"unable to convert "{}" into a variant of `Alert`"#, s); - } - })) - } -} - -pub struct AlertAndLevelWrapper(Alert, AlertLevel); -impl FromStr for AlertAndLevelWrapper { - type Err = String; - fn from_str(s: &str) -> Result { - let word_vec: Vec<_> = s.rsplitn(2, ' ').collect(); - let alert: AlertWrapper = word_vec[1].parse()?; - let level: AlertLevelWrapper = word_vec[0].parse()?; - Ok(Self(alert.0, level.0)) - } -} -impl Into<(Alert, AlertLevel)> for AlertAndLevelWrapper { - fn into(self) -> (Alert, AlertLevel) { - (self.0, self.1) - } -} - -// AircraftState generator -type Prng = rand_pcg::Mcg128Xsl64; -pub struct AircraftStateGenerator(pub Prng); - -impl Default for AircraftStateGenerator { - fn default() -> Self { - Self(Prng::new(0xcafef00dd15ea5e5)) - } -} - -impl Iterator for AircraftStateGenerator { - type Item = AircraftState; - - fn next(&mut self) -> Option { - let bytes_needed = AircraftStateWrapper::size_hint(0).0; - let mut buf = Vec::with_capacity(bytes_needed); - while buf.len() < bytes_needed { - buf.extend_from_slice(&self.0.next_u64().to_le_bytes()); - } - let mut u = Unstructured::new(&mut buf); - - Some(AircraftStateWrapper::arbitrary(&mut u).unwrap().0) // the unwrap is safe, we guarantee that enough bytes are available - } -} - -// for the lack of a better word -pub trait PressMould { - fn at_least(&mut self, value: &mut T, at_least: T); - fn at_most(&mut self, value: &mut T, at_most: T); - fn in_range(&mut self, value: &mut T, at_least: T, at_most: T); - fn not_in_range(&mut self, value: &mut T, range_from: T, range_to: T); -} - -// Stupid -pub struct BouncingClamp(); - -impl PressMould for BouncingClamp -where - T: Copy - + Clone - + std::fmt::Debug - + PartialOrd - + Add - + Rem - + Sub - + Abs, -{ - fn at_least(&mut self, value: &mut T, at_least: T) { - if *value < at_least { - *value = at_least + (at_least - *value) - } - assert!(*value >= at_least); - } - - fn at_most(&mut self, value: &mut T, at_most: T) { - if *value > at_most { - *value = at_most - (*value - at_most) - } - assert!(*value <= at_most); - } - - fn in_range(&mut self, value: &mut T, at_least: T, at_most: T) { - assert!(at_least <= at_most); - - if at_least == at_most { - *value = at_least; - return; - } - - let modulo = |a: T, b: T| ((a % b) + b) % b; - - let span = at_most - at_least; - let bounced = (modulo(*value + span, span + span) - span).abs(); - *value = bounced + at_least; - - assert!(at_least <= *value && *value <= at_most); - } - - fn not_in_range(&mut self, value: &mut T, at_most: T, at_least: T) { - assert!(at_most <= at_least); - if *value > at_most && *value < at_least { - *value = *value + (at_least - at_most); - } - assert!(*value < at_least || at_most < *value); - } -} - -pub trait Abs: Sized { - fn abs(self) -> Self; -} - -impl Abs for f64 { - fn abs(self) -> Self { - self.abs() - } -} - -impl Abs for uom::si::Quantity -where - D: uom::si::Dimension, - U: uom::si::Units, - V: uom::num_traits::Num + uom::Conversion + Signed, -{ - fn abs(self) -> Self { - self.abs() - } -} +pub mod aircraft_state; +pub mod constraints; +pub mod parameters; +pub mod world; diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs new file mode 100644 index 0000000..9aee731 --- /dev/null +++ b/taws_minimal/tests/util/parameters.rs @@ -0,0 +1,168 @@ +use std::str::FromStr; + +use cucumber::Parameter; +use lazy_static::lazy_static; +use opentaws::{Alert, AlertLevel}; +use regex::Regex; +use uom::si::f64::Length; +use uom::si::length; + +use super::constraints::Constraint; + +pub struct MaybeParameter(bool); + +impl Into for MaybeParameter { + fn into(self) -> bool { + self.0 + } +} + +impl FromStr for MaybeParameter { + type Err = String; + + fn from_str(s: &str) -> Result { + let mut maybe = s.trim().to_lowercase(); + maybe.retain(|c| !c.is_whitespace()); + match maybe.as_str() { + "is" | "should" | "shall" => Ok(Self(true)), + "isnot" | "shouldnot" | "shallnot" => Ok(Self(false)), + _ => Err(format!("unknown word: {s}")), + } + } +} + +impl Parameter for MaybeParameter { + const NAME: &'static str = "maybe"; + const REGEX: &'static str = "(?:is|should|shall)\\s*(?:not)?"; +} + +pub struct AlertParameter(Alert); + +impl FromStr for AlertParameter { + type Err = String; + + fn from_str(s: &str) -> Result { + let mut alert = s.trim().to_lowercase(); + alert.retain(|c| !c.is_whitespace()); + match alert.as_str() { + "ffac" => Ok(Self(Alert::Ffac)), + "flta" => Ok(Self(Alert::Flta)), + "mode1" => Ok(Self(Alert::Mode1)), + "mode2" => Ok(Self(Alert::Mode2)), + "mode3" => Ok(Self(Alert::Mode3)), + "mode4" => Ok(Self(Alert::Mode4)), + "mode5" => Ok(Self(Alert::Mode5)), + "pda" => Ok(Self(Alert::Pda)), + _ => Err(format!("unknown alert: {s}")), + } + } +} + +impl Into for AlertParameter { + fn into(self) -> Alert { + self.0 + } +} + +impl Parameter for AlertParameter { + const NAME: &'static str = "alert"; + const REGEX: &'static str = "(?:[a-zA-Z]+\\s*[0-9]*)"; +} + +pub struct AlertLevelParameter(AlertLevel); + +impl Into for AlertLevelParameter { + fn into(self) -> AlertLevel { + self.0 + } +} + +impl FromStr for AlertLevelParameter { + type Err = String; + + fn from_str(s: &str) -> Result { + let mut alert_level = s.trim().to_lowercase(); + alert_level.retain(|c| !c.is_whitespace()); + match alert_level.as_str() { + "warning" => Ok(Self(AlertLevel::Warning)), + "caution" => Ok(Self(AlertLevel::Caution)), + "annunciation" => Ok(Self(AlertLevel::Annunciation)), + _ => Err(format!("invalid alert level: {}", s)), + } + } +} + +impl Parameter for AlertLevelParameter { + const NAME: &'static str = "alert_level"; + const REGEX: &'static str = "(?:[Ww]arning|[Cc]aution|[Aa]nnunciation)"; +} + +pub struct ConstraintParameter(Constraint); + +impl FromStr for ConstraintParameter { + type Err = String; + + fn from_str(s: &str) -> Result { + const PATTERN: &str = concat!( + "(?Pat least|at most|within|between|not between)", + "\\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+)", + "(?:\\s*and\\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+))?" + ); + + lazy_static! { + static ref REGEX: Regex = Regex::new(PATTERN).unwrap(); + } + + let captures = REGEX.captures(s).ok_or("invalid constraint string")?; + let typ = captures + .name("type") + .ok_or("constaint type not found")? + .as_str(); + let q1 = captures.name("q1").ok_or("quantity not found")?.as_str(); + let q2 = captures.name("q2").map(|x| x.as_str()); + + let q1 = q1.parse::().map_err(|_| "invalid quantity format")?; + let q2 = q2 + .map(|x| x.parse::()) + .transpose() + .map_err(|_| "invalid quantity format")?; + + match typ { + "at least" => match q2 { + Some(_) => Err(format!("unexpected: {}", s)), + None => Ok(Self(Constraint::AtLeast(0, q1))), + }, + "at most" | "within" => match q2 { + Some(_) => Err(format!("unexpected: {}", s)), + None => Ok(Self(Constraint::AtMost(0, q1))), + }, + "between" => match q2 { + Some(q2) if q1 <= q2 => Ok(Self(Constraint::InRange(0, q1, q2))), + Some(q2) => Ok(Self(Constraint::InRange(0, q2, q1))), + None => Err(format!("missing second bound: {}", s)), + }, + "not between" => match q2 { + Some(q2) if q1 <= q2 => Ok(Self(Constraint::NotInRange(0, q1, q2))), + Some(q2) => Ok(Self(Constraint::NotInRange(0, q2, q1))), + None => Err(format!("missing second bound: {}", s)), + }, + _ => Err(format!("invalid constraint type: {}", s)), + } + } +} + +impl Into> for ConstraintParameter { + fn into(self) -> Constraint { + self.0 + } +} + +impl Parameter for ConstraintParameter { + const NAME: &'static str = "constraint"; + + const REGEX: &'static str = concat!( + "(?:at least|at most|within|between|not between)", + "\\s*[+-]?(?:[0-9]*[.])?[0-9]+", + "(?:\\s*and\\s*[+-]?(?:[0-9]*[.])?[0-9]+)?" + ); +} diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs new file mode 100644 index 0000000..0603d75 --- /dev/null +++ b/taws_minimal/tests/util/world.rs @@ -0,0 +1,49 @@ +use std::convert::Infallible; + +use async_trait::async_trait; +use cucumber::WorldInit; +use opentaws::prelude::*; +use taws_minimal::MinimalTaws; + +use super::constraints::{AircraftStateConstraints, ConstraintAirportDatabase}; + +static AIRPORT_DATABASE: ConstraintAirportDatabase = ConstraintAirportDatabase {}; + +lazy_static::lazy_static! { + static ref TAWS_CONFIG: TawsConfig<'static> = TawsConfig{ + terrain_server: &AIRPORT_DATABASE, + max_climbrate: Velocity::new::(700.0), + max_climbrate_change: Acceleration::new::(100.0), + }; +} + +#[derive(WorldInit)] +pub struct MyWorld { + pub taws: MinimalTaws<'static>, + pub constraints: Vec, + pub test_length: usize, + pub phase: usize, +} + +#[async_trait(?Send)] +impl cucumber::World for MyWorld { + type Error = Infallible; + + async fn new() -> Result { + Ok(Self { + taws: MinimalTaws::new(&TAWS_CONFIG), + constraints: vec![AircraftStateConstraints::default()], + test_length: 10, + phase: 0, + }) + } +} + +impl std::fmt::Debug for MyWorld { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MyWorld").finish() + //todo!(); + } +} + +impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? From f3319a32d42ed95d7425588a71d1f8568bd6e442 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 13:50:05 +0200 Subject: [PATCH 22/73] fix: use raw string literals for regexprs. --- taws_minimal/tests/util/parameters.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs index 9aee731..547c39b 100644 --- a/taws_minimal/tests/util/parameters.rs +++ b/taws_minimal/tests/util/parameters.rs @@ -33,7 +33,7 @@ impl FromStr for MaybeParameter { impl Parameter for MaybeParameter { const NAME: &'static str = "maybe"; - const REGEX: &'static str = "(?:is|should|shall)\\s*(?:not)?"; + const REGEX: &'static str = r"(?:is|should|shall)\s*(?:not)?"; } pub struct AlertParameter(Alert); @@ -66,7 +66,7 @@ impl Into for AlertParameter { impl Parameter for AlertParameter { const NAME: &'static str = "alert"; - const REGEX: &'static str = "(?:[a-zA-Z]+\\s*[0-9]*)"; + const REGEX: &'static str = r"(?:[a-zA-Z]+\s*[0-9]*)"; } pub struct AlertLevelParameter(AlertLevel); @@ -104,9 +104,9 @@ impl FromStr for ConstraintParameter { fn from_str(s: &str) -> Result { const PATTERN: &str = concat!( - "(?Pat least|at most|within|between|not between)", - "\\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+)", - "(?:\\s*and\\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+))?" + r"(?Pat least|at most|within|between|not between)", + r"\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+)", + r"(?:\s*and\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+))?" ); lazy_static! { @@ -161,8 +161,8 @@ impl Parameter for ConstraintParameter { const NAME: &'static str = "constraint"; const REGEX: &'static str = concat!( - "(?:at least|at most|within|between|not between)", - "\\s*[+-]?(?:[0-9]*[.])?[0-9]+", - "(?:\\s*and\\s*[+-]?(?:[0-9]*[.])?[0-9]+)?" + r"(?:at least|at most|within|between|not between)\s*", + r"[+-]?(?:[0-9]*[.])?[0-9]+", + r"(?:\s*and\s*[+-]?(?:[0-9]*[.])?[0-9]+)?" ); } From a73046b1cdbc5ff1b8fb78d4de84c7ceddefa9fe Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 13:52:17 +0200 Subject: [PATCH 23/73] fix: remove unused stuff --- taws_minimal/tests/cucumber.rs | 20 -------- .../tests/util/constraints/constraint.rs | 46 ------------------- taws_minimal/tests/util/world.rs | 1 - 3 files changed, 67 deletions(-) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 297f88b..51f4411 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -85,8 +85,6 @@ fn given_height_above_terrain(world: &mut MyWorld, height_above_terrain: Constra Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, a * unit, b * unit), }; - //let height_above_terrain = height_above_terrain * Length::new::(1.0); - world.constraints[world.phase].add_altitude_ground_constraint(height_above_terrain); } @@ -172,16 +170,7 @@ fn then_alert_emitted( let alert_state = world.taws.process(&frame); let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); - //println!("{:#?}", alert_state); assert_eq!(emitted, should_emit); - //alert_state.iter().filter(|(a, l)| a == alert). - // Make sure we are in the last phase of this scenario with "c + 1 == world.constraints.len()" - /*if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { - panic!( - "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", - frame, alert_state - ); - }*/ } } @@ -208,15 +197,6 @@ fn then_alert_emitted_within( let alert_state = world.taws.process(&frame); let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); - //println!("{:#?}", alert_state); assert_eq!(emitted, should_emit); - //alert_state.iter().filter(|(a, l)| a == alert). - // Make sure we are in the last phase of this scenario with "c + 1 == world.constraints.len()" - /*if c + 1 == n_constraints && alert_state.iter().any(|(a, l)| a == alert && l <= level) { - panic!( - "Aicraft state that violated the scenario: {:#?}\nalerts emitted: {:#?}", - frame, alert_state - ); - }*/ } } diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index 58ea0ba..726a6be 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -98,49 +98,3 @@ where } } } - -/*impl std::ops::Mul for Constraint -where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Add - + std::ops::Rem - + std::ops::Rem - + std::ops::Sub - + std::ops::Sub - + press_mould::Abs - + std::fmt::Debug - + std::ops::Mul, - R: Copy + Zero + PartialOrd, - Z: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Add - + std::ops::Rem - + std::ops::Rem - + std::ops::Sub - + std::ops::Sub - + press_mould::Abs - + std::fmt::Debug, -{ - type Output = Constraint; - - fn mul(self, r: R) -> Constraint { - let zero = R::zero(); - match self { - Constraint::AtLeast(x, y) if r >= zero => Constraint::AtLeast(x, y * r), - Constraint::AtLeast(x, y) if r < zero => Constraint::AtMost(x, y * r), - Constraint::AtMost(x, y) if r >= zero => Constraint::AtMost(x, y * r), - Constraint::AtMost(x, y) if r < zero => Constraint::AtLeast(x, y * r), - Constraint::Equal(x, y) => Constraint::Equal(x, y * r), - Constraint::InRange(x, a, b) if r >= zero => Constraint::InRange(x, a * r, b * r), - Constraint::InRange(x, a, b) if r < zero => Constraint::InRange(x, b * r, a * r), - Constraint::NotInRange(x, a, b) if r >= zero => Constraint::NotInRange(x, a * r, b * r), - Constraint::NotInRange(x, a, b) if r < zero => Constraint::NotInRange(x, b * r, a * r), - _ => panic!("cannot happen"), - } - } -}*/ diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs index 0603d75..145d65d 100644 --- a/taws_minimal/tests/util/world.rs +++ b/taws_minimal/tests/util/world.rs @@ -42,7 +42,6 @@ impl cucumber::World for MyWorld { impl std::fmt::Debug for MyWorld { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("MyWorld").finish() - //todo!(); } } From f7eada8767cacaf49c1fd8853f7d09ffc95e4c26 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 13:54:31 +0200 Subject: [PATCH 24/73] fix: remove cucumber steps with todos. --- taws_minimal/tests/cucumber.rs | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 51f4411..083e080 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -120,29 +120,6 @@ fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: Constrain world.constraints[world.phase].add_altitude_ground_constraint(height_above_ground); } -#[given(expr = "the plane is {constraint} NM of an airport")] -#[when(expr = "the distance to the nearest airport is {constraint} NM")] -fn when_distance_to_airport(_world: &mut MyWorld, _distance: ConstraintParameter) { - todo!(); -} - -#[when(expr = "a failure is detected by the continuos monitoring")] -#[when(expr = "the initiated self-test detects a failure")] -fn when_failure_detected(world: &mut MyWorld) { - todo!(); -} - -#[given(expr = "the self-test is initiated")] -#[when(expr = "the self-test is initiated")] -fn when_self_test_initiated(_world: &mut MyWorld) { - todo!(); -} - -#[when(expr = "the rate of input data reduces or stagnates")] -fn when_data_rate_reduces(_world: &mut MyWorld) { - todo!(); -} - #[then(expr = "{alert} {maybe} be armed")] fn then_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { assert_eq!(world.taws.is_armed(alert.into()), maybe.into()) From 1f988abe1b35356d374f42b0fc86bdf2e30e9be4 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 13:56:05 +0200 Subject: [PATCH 25/73] fix: regex version --- taws_minimal/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index 812cf61..27948d9 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -49,7 +49,7 @@ rand_pcg = { version = "*", optional = true } rayon = { version = "1.5", optional = true } serde_json = { version = "1.0", optional = true } smol = { version = "1", optional = true } -regex = "1.6.0" +regex = "1" [[test]] From 115d69ae8d2fa594f9ff227ce7100fa9b1b7ad16 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 14:03:38 +0200 Subject: [PATCH 26/73] fix: constraint type bounds --- taws_minimal/tests/util/constraints/constraint.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index 726a6be..cf10307 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -9,12 +9,9 @@ pub enum Constraint where Q: Copy + PartialOrd - + PartialEq - + std::ops::Add + + PartialEq + std::ops::Add - + std::ops::Rem + std::ops::Rem - + std::ops::Sub + std::ops::Sub + press_mould::Abs + std::fmt::Debug, @@ -30,12 +27,9 @@ impl Constraint where Q: Copy + PartialOrd - + PartialEq - + std::ops::Add + + PartialEq + std::ops::Add - + std::ops::Rem + std::ops::Rem - + std::ops::Sub + std::ops::Sub + press_mould::Abs + std::fmt::Debug, From 6f77642b2e8e27b438edb1cc1ab1b045b1e37122 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 24 Aug 2022 14:20:48 +0200 Subject: [PATCH 27/73] fix: removed the mould out out openTAWS --- taws_minimal/tests/util/constraints/aircraft_state.rs | 8 ++++---- taws_minimal/tests/util/constraints/constraint.rs | 8 ++++---- .../{press_mould.rs => constraint_enforcement.rs} | 4 ++-- taws_minimal/tests/util/constraints/mod.rs | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) rename taws_minimal/tests/util/constraints/{press_mould.rs => constraint_enforcement.rs} (96%) diff --git a/taws_minimal/tests/util/constraints/aircraft_state.rs b/taws_minimal/tests/util/constraints/aircraft_state.rs index b28637b..4167447 100644 --- a/taws_minimal/tests/util/constraints/aircraft_state.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state.rs @@ -1,4 +1,4 @@ -use super::{constraint::Constraint, press_mould}; +use super::{constraint::Constraint, constraint_enforcement}; use opentaws::AircraftState; use uom::si::f64::{Angle, Length, Velocity}; @@ -31,7 +31,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + press_mould::Abs + + constraint_enforcement::Abs + std::fmt::Debug, { let mut i = 0; @@ -57,7 +57,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + press_mould::Abs + + constraint_enforcement::Abs + std::fmt::Debug, { let mut cs = Vec::new(); @@ -127,7 +127,7 @@ impl AircraftStateConstraints { + std::ops::Rem + std::ops::Sub + std::ops::Sub - + press_mould::Abs + + constraint_enforcement::Abs + std::fmt::Debug, { let merged = Self::merge(constraints); diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index cf10307..f58c2e7 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -2,7 +2,7 @@ use std::any::Any; use uom::num_traits::{Signed, Zero}; -use super::press_mould::{self, PressMould}; +use super::constraint_enforcement::{self, ConstraintEnforcer}; #[derive(Clone, PartialEq, Debug)] pub enum Constraint @@ -13,7 +13,7 @@ where + std::ops::Add + std::ops::Rem + std::ops::Sub - + press_mould::Abs + + constraint_enforcement::Abs + std::fmt::Debug, { AtLeast(usize, Q), @@ -31,7 +31,7 @@ where + std::ops::Add + std::ops::Rem + std::ops::Sub - + press_mould::Abs + + constraint_enforcement::Abs + std::fmt::Debug, { pub fn phase(&self) -> usize { @@ -45,7 +45,7 @@ where } pub fn apply_to(&self, quantity: &mut Q) { - let mut bouncer = press_mould::BouncingClamp(); + let mut bouncer = constraint_enforcement::BouncingClamp(); match self { Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), diff --git a/taws_minimal/tests/util/constraints/press_mould.rs b/taws_minimal/tests/util/constraints/constraint_enforcement.rs similarity index 96% rename from taws_minimal/tests/util/constraints/press_mould.rs rename to taws_minimal/tests/util/constraints/constraint_enforcement.rs index 2fd1268..885d66a 100644 --- a/taws_minimal/tests/util/constraints/press_mould.rs +++ b/taws_minimal/tests/util/constraints/constraint_enforcement.rs @@ -3,7 +3,7 @@ use std::ops::{Add, Rem, Sub}; use uom::num_traits::Signed; // for the lack of a better word -pub trait PressMould { +pub trait ConstraintEnforcer { fn at_least(&mut self, value: &mut T, at_least: T); fn at_most(&mut self, value: &mut T, at_most: T); fn in_range(&mut self, value: &mut T, at_least: T, at_most: T); @@ -13,7 +13,7 @@ pub trait PressMould { // Stupid pub struct BouncingClamp(); -impl PressMould for BouncingClamp +impl ConstraintEnforcer for BouncingClamp where T: Copy + Clone diff --git a/taws_minimal/tests/util/constraints/mod.rs b/taws_minimal/tests/util/constraints/mod.rs index 4e76f4e..a95063c 100644 --- a/taws_minimal/tests/util/constraints/mod.rs +++ b/taws_minimal/tests/util/constraints/mod.rs @@ -1,9 +1,9 @@ mod aircraft_state; mod airport_database; mod constraint; -mod press_mould; +mod constraint_enforcement; pub use aircraft_state::*; pub use airport_database::*; pub use constraint::*; -pub use press_mould::*; +pub use constraint_enforcement::*; From 7ac071d4dc3bde5f33ad65a8afad9b1d73bcd4ff Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 29 Aug 2022 10:05:59 +0200 Subject: [PATCH 28/73] fix: remove todo/empty cucumber step --- taws_minimal/tests/cucumber.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 083e080..0f2fff8 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -40,16 +40,6 @@ fn given_alert_inhibited(world: &mut MyWorld, alert: AlertParameter, maybe: Mayb } } -#[given(expr = "a {alert} {alert_level} alert {maybe} active")] -fn given_alert_level_active( - _world: &mut MyWorld, - _alert: AlertParameter, - _level: AlertLevelParameter, - _maybe: MaybeParameter, -) { - todo!() -} - #[given(expr = "steep approach {maybe} selected")] fn given_steep_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { world.constraints[world.phase].add_steep_approach_constraint(maybe.into()); From d284f2d65be8253346ae9523c11bc6b6b7e185dc Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 29 Aug 2022 10:08:44 +0200 Subject: [PATCH 29/73] factor out ConstraintEnforcer impl from AircraftStateConstraints --- taws_minimal/tests/cucumber.rs | 6 ++- ..._state.rs => aircraft_state_constraint.rs} | 41 +++++++++---------- .../tests/util/constraints/constraint.rs | 7 +++- .../constraints/constraint_enforcement.rs | 1 + taws_minimal/tests/util/constraints/mod.rs | 4 +- 5 files changed, 32 insertions(+), 27 deletions(-) rename taws_minimal/tests/util/constraints/{aircraft_state.rs => aircraft_state_constraint.rs} (84%) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 0f2fff8..ee31744 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -11,6 +11,8 @@ use util::constraints::Constraint; use util::parameters::*; use util::world::MyWorld; +use crate::util::constraints::BouncingClamp; + fn main() { smol::block_on(MyWorld::run("features")); } @@ -133,7 +135,7 @@ fn then_alert_emitted( .enumerate() .map(|(c, f)| (c % n_constraints, f)) { - world.constraints[c].apply_to(&mut frame); + world.constraints[c].apply_to::(&mut frame); let alert_state = world.taws.process(&frame); let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); @@ -160,7 +162,7 @@ fn then_alert_emitted_within( .enumerate() .map(|(c, f)| (c % n_constraints, f)) { - world.constraints[c].apply_to(&mut frame); + world.constraints[c].apply_to::(&mut frame); let alert_state = world.taws.process(&frame); let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); diff --git a/taws_minimal/tests/util/constraints/aircraft_state.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraint.rs similarity index 84% rename from taws_minimal/tests/util/constraints/aircraft_state.rs rename to taws_minimal/tests/util/constraints/aircraft_state_constraint.rs index 4167447..64e57a7 100644 --- a/taws_minimal/tests/util/constraints/aircraft_state.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state_constraint.rs @@ -1,7 +1,8 @@ -use super::{constraint::Constraint, constraint_enforcement}; -use opentaws::AircraftState; +use opentaws::prelude::*; use uom::si::f64::{Angle, Length, Velocity}; +use super::{constraint_enforcement, Constraint, ConstraintEnforcer}; + #[derive(Clone, Default, PartialEq)] pub struct AircraftStateConstraints { altitude: Vec>, @@ -25,11 +26,8 @@ impl AircraftStateConstraints { Q: Copy + PartialOrd + PartialEq - + std::ops::Add + std::ops::Add - + std::ops::Rem + std::ops::Rem - + std::ops::Sub + std::ops::Sub + constraint_enforcement::Abs + std::fmt::Debug, @@ -51,11 +49,8 @@ impl AircraftStateConstraints { Q: Copy + PartialOrd + PartialEq - + std::ops::Add + std::ops::Add - + std::ops::Rem + std::ops::Rem - + std::ops::Sub + std::ops::Sub + constraint_enforcement::Abs + std::fmt::Debug, @@ -116,37 +111,41 @@ impl AircraftStateConstraints { cs } - fn apply(constraints: &[Constraint], state: &mut Q) + fn apply(constraints: &[Constraint], state: &mut Q) where Q: Copy + PartialOrd + PartialEq - + std::ops::Add + std::ops::Add - + std::ops::Rem + std::ops::Rem - + std::ops::Sub + std::ops::Sub + constraint_enforcement::Abs + std::fmt::Debug, + TEnforcer: ConstraintEnforcer + Default, { let merged = Self::merge(constraints); for c in &merged { - c.apply_to(state) + c.apply_to::(state) } for c in constraints { c.check(*state) } } - pub fn apply_to(&self, state: &mut AircraftState) { - Self::apply(&self.altitude, &mut state.altitude); - Self::apply(&self.altitude_ground, &mut state.altitude_ground); - Self::apply(&self.climb_rate, &mut state.climb_rate); - Self::apply(&self.speed_air, &mut state.speed_air); - Self::apply(&self.heading, &mut state.heading); - Self::apply(&self.pitch, &mut state.pitch); - Self::apply(&self.roll, &mut state.roll); + pub fn apply_to(&self, state: &mut AircraftState) + where + TEnforcer: ConstraintEnforcer + + ConstraintEnforcer + + ConstraintEnforcer + + Default, + { + Self::apply::(&self.altitude, &mut state.altitude); + Self::apply::(&self.altitude_ground, &mut state.altitude_ground); + Self::apply::(&self.climb_rate, &mut state.climb_rate); + Self::apply::(&self.speed_air, &mut state.speed_air); + Self::apply::(&self.heading, &mut state.heading); + Self::apply::(&self.pitch, &mut state.pitch); + Self::apply::(&self.roll, &mut state.roll); //TODO Change when bools get vec state.steep_approach = self.steep_approach; diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index f58c2e7..2adb97a 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -44,8 +44,11 @@ where } } - pub fn apply_to(&self, quantity: &mut Q) { - let mut bouncer = constraint_enforcement::BouncingClamp(); + pub fn apply_to(&self, quantity: &mut Q) + where + TEnforcer: ConstraintEnforcer + Default, + { + let mut bouncer = TEnforcer::default(); match self { Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), diff --git a/taws_minimal/tests/util/constraints/constraint_enforcement.rs b/taws_minimal/tests/util/constraints/constraint_enforcement.rs index 885d66a..9c0bc14 100644 --- a/taws_minimal/tests/util/constraints/constraint_enforcement.rs +++ b/taws_minimal/tests/util/constraints/constraint_enforcement.rs @@ -11,6 +11,7 @@ pub trait ConstraintEnforcer { } // Stupid +#[derive(Default)] pub struct BouncingClamp(); impl ConstraintEnforcer for BouncingClamp diff --git a/taws_minimal/tests/util/constraints/mod.rs b/taws_minimal/tests/util/constraints/mod.rs index a95063c..7ffb39b 100644 --- a/taws_minimal/tests/util/constraints/mod.rs +++ b/taws_minimal/tests/util/constraints/mod.rs @@ -1,9 +1,9 @@ -mod aircraft_state; +mod aircraft_state_constraint; mod airport_database; mod constraint; mod constraint_enforcement; -pub use aircraft_state::*; +pub use aircraft_state_constraint::*; pub use airport_database::*; pub use constraint::*; pub use constraint_enforcement::*; From cca0a5b3bc161d9f68823ec38d636594d276a3fe Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 5 Sep 2022 00:21:29 +0200 Subject: [PATCH 30/73] fix(taws_minimal): Refactor Constraint and AircraftStateConstraints --- taws_minimal/tests/cucumber.rs | 30 +-- .../constraints/aircraft_state_constraint.rs | 214 ------------------ .../constraints/aircraft_state_constraints.rs | 126 +++++++++++ .../tests/util/constraints/constraint.rs | 122 ++++++++-- taws_minimal/tests/util/constraints/mod.rs | 4 +- taws_minimal/tests/util/parameters.rs | 12 +- 6 files changed, 250 insertions(+), 258 deletions(-) delete mode 100644 taws_minimal/tests/util/constraints/aircraft_state_constraint.rs create mode 100644 taws_minimal/tests/util/constraints/aircraft_state_constraints.rs diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index ee31744..6358226 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -70,11 +70,11 @@ fn given_height_above_terrain(world: &mut MyWorld, height_above_terrain: Constra let unit = Length::new::(1.0); let height_above_terrain = match height_above_terrain { - Constraint::AtLeast(p, a) => Constraint::AtLeast(p, a * unit), - Constraint::AtMost(p, a) => Constraint::AtMost(p, a * unit), - Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), - Constraint::InRange(p, a, b) => Constraint::InRange(p, a * unit, b * unit), - Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, a * unit, b * unit), + Constraint::AtLeast(a) => Constraint::AtLeast(a * unit), + Constraint::AtMost(a) => Constraint::AtMost(a * unit), + Constraint::Equal(a) => Constraint::Equal(a * unit), + Constraint::InRange(a, b) => Constraint::InRange(a * unit, b * unit), + Constraint::NotInRange(a, b) => Constraint::NotInRange(a * unit, b * unit), }; world.constraints[world.phase].add_altitude_ground_constraint(height_above_terrain); @@ -86,11 +86,11 @@ fn when_rate_of_descent(world: &mut MyWorld, rate_of_descent: ConstraintParamete let unit = Velocity::new::(-1.0); let climb_rate = match rate_of_descent { - Constraint::AtLeast(p, a) => Constraint::AtMost(p, a * unit), - Constraint::AtMost(p, a) => Constraint::AtLeast(p, a * unit), - Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), - Constraint::InRange(p, a, b) => Constraint::InRange(p, b * unit, a * unit), - Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, b * unit, a * unit), + Constraint::AtLeast(a) => Constraint::AtMost(a * unit), + Constraint::AtMost(a) => Constraint::AtLeast(a * unit), + Constraint::Equal(a) => Constraint::Equal(a * unit), + Constraint::InRange(a, b) => Constraint::InRange(b * unit, a * unit), + Constraint::NotInRange(a, b) => Constraint::NotInRange(b * unit, a * unit), }; world.constraints[world.phase].add_climb_rate_constraint(climb_rate); @@ -102,11 +102,11 @@ fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: Constrain let unit = Length::new::(1.0); let height_above_ground = match height_above_ground { - Constraint::AtLeast(p, a) => Constraint::AtLeast(p, a * unit), - Constraint::AtMost(p, a) => Constraint::AtMost(p, a * unit), - Constraint::Equal(p, a) => Constraint::Equal(p, a * unit), - Constraint::InRange(p, a, b) => Constraint::InRange(p, a * unit, b * unit), - Constraint::NotInRange(p, a, b) => Constraint::NotInRange(p, a * unit, b * unit), + Constraint::AtLeast(a) => Constraint::AtLeast(a * unit), + Constraint::AtMost(a) => Constraint::AtMost(a * unit), + Constraint::Equal(a) => Constraint::Equal(a * unit), + Constraint::InRange(a, b) => Constraint::InRange(a * unit, b * unit), + Constraint::NotInRange(a, b) => Constraint::NotInRange(a * unit, b * unit), }; world.constraints[world.phase].add_altitude_ground_constraint(height_above_ground); diff --git a/taws_minimal/tests/util/constraints/aircraft_state_constraint.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraint.rs deleted file mode 100644 index 64e57a7..0000000 --- a/taws_minimal/tests/util/constraints/aircraft_state_constraint.rs +++ /dev/null @@ -1,214 +0,0 @@ -use opentaws::prelude::*; -use uom::si::f64::{Angle, Length, Velocity}; - -use super::{constraint_enforcement, Constraint, ConstraintEnforcer}; - -#[derive(Clone, Default, PartialEq)] -pub struct AircraftStateConstraints { - altitude: Vec>, - altitude_ground: Vec>, - climb_rate: Vec>, - speed_air: Vec>, - heading: Vec>, - pitch: Vec>, - roll: Vec>, - //TODO use vector with bool and phase - steep_approach: bool, - precision_approach: bool, - go_around: bool, - take_of: bool, -} - -impl AircraftStateConstraints { - //Retains constraints from the current phase - fn filter_phase(constraints: &mut Vec>, current_phase: usize) - where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Rem - + std::ops::Sub - + constraint_enforcement::Abs - + std::fmt::Debug, - { - let mut i = 0; - while i < constraints.len() { - if constraints[i].phase() != current_phase { - constraints.remove(i); - } else { - i += 1; - } - } - } - - //Merges constraints - //Especially important for merging < and > constraints into one InRange constraint - fn merge(constraints: &[Constraint]) -> Vec> - where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Rem - + std::ops::Sub - + constraint_enforcement::Abs - + std::fmt::Debug, - { - let mut cs = Vec::new(); - let mut at_least = None; - let mut at_most = None; - - for c in constraints { - match c { - Constraint::AtLeast(_, q) => { - if at_least.map_or(true, |a| q > a) { - at_least = Some(q); - } - } - Constraint::AtMost(_, q) => { - if at_most.map_or(true, |a| q < a) { - at_most = Some(q); - } - } - Constraint::InRange(_, l, r) => { - if at_least.map_or(true, |a| l > a) { - at_least = Some(l); - } - if at_most.map_or(true, |a| r < a) { - at_most = Some(r); - } - } - _ => cs.push(c.clone()), - } - } - - match (at_least, at_most) { - (Some(at_least), Some(at_most)) => { - assert!( - at_least <= at_most, - "Left bound ({:?}) is greater than right bound ({:?})", - at_least, - at_most - ); - cs.push(Constraint::InRange( - constraints.first().unwrap().phase(), - *at_least, - *at_most, - )); - } - (Some(at_least), None) => cs.push(Constraint::AtLeast( - constraints.first().unwrap().phase(), - *at_least, - )), - (None, Some(at_most)) => cs.push(Constraint::AtMost( - constraints.first().unwrap().phase(), - *at_most, - )), - _ => {} - } - - cs - } - - fn apply(constraints: &[Constraint], state: &mut Q) - where - Q: Copy - + PartialOrd - + PartialEq - + std::ops::Add - + std::ops::Rem - + std::ops::Sub - + constraint_enforcement::Abs - + std::fmt::Debug, - TEnforcer: ConstraintEnforcer + Default, - { - let merged = Self::merge(constraints); - for c in &merged { - c.apply_to::(state) - } - for c in constraints { - c.check(*state) - } - } - - pub fn apply_to(&self, state: &mut AircraftState) - where - TEnforcer: ConstraintEnforcer - + ConstraintEnforcer - + ConstraintEnforcer - + Default, - { - Self::apply::(&self.altitude, &mut state.altitude); - Self::apply::(&self.altitude_ground, &mut state.altitude_ground); - Self::apply::(&self.climb_rate, &mut state.climb_rate); - Self::apply::(&self.speed_air, &mut state.speed_air); - Self::apply::(&self.heading, &mut state.heading); - Self::apply::(&self.pitch, &mut state.pitch); - Self::apply::(&self.roll, &mut state.roll); - - //TODO Change when bools get vec - state.steep_approach = self.steep_approach; - state.precision_approach = self.precision_approach; - state.go_around = self.go_around; - state.take_off = self.take_of; - } - - pub fn add_altitude_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.altitude.push(c); - Self::filter_phase(self.altitude.as_mut(), phase) - } - - pub fn add_altitude_ground_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.altitude_ground.push(c); - Self::filter_phase(self.altitude_ground.as_mut(), phase) - } - - pub fn add_climb_rate_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.climb_rate.push(c); - Self::filter_phase(self.climb_rate.as_mut(), phase) - } - - pub fn add_speed_air_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.speed_air.push(c); - Self::filter_phase(self.speed_air.as_mut(), phase) - } - - pub fn add_heading_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.heading.push(c); - Self::filter_phase(self.heading.as_mut(), phase) - } - - pub fn add_pitch_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.pitch.push(c); - Self::filter_phase(self.pitch.as_mut(), phase) - } - - pub fn add_roll_constraint(&mut self, c: Constraint) { - let phase = c.phase(); - self.roll.push(c); - Self::filter_phase(self.roll.as_mut(), phase) - } - - pub fn add_steep_approach_constraint(&mut self, c: bool) { - self.steep_approach = c; - } - - pub fn add_precision_approach_constraint(&mut self, c: bool) { - self.precision_approach = c; - } - - pub fn add_go_around_constraint(&mut self, c: bool) { - self.go_around = c; - } - - pub fn add_take_off_constraint(&mut self, c: bool) { - self.take_of = c; - } -} diff --git a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs new file mode 100644 index 0000000..67c841e --- /dev/null +++ b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs @@ -0,0 +1,126 @@ +use opentaws::prelude::*; +use uom::si::f64::{Angle, Length, Velocity}; + +use super::{constraint_enforcement, Constraint, ConstraintEnforcer}; + +#[derive(Clone, Default, PartialEq)] +pub struct AircraftStateConstraints { + altitude: Option>, + altitude_ground: Option>, + climb_rate: Option>, + speed_air: Option>, + heading: Option>, + pitch: Option>, + roll: Option>, + + steep_approach: bool, + precision_approach: bool, + go_around: bool, + take_off: bool, +} + +impl AircraftStateConstraints { + fn apply(constraint: &Option>, state: &mut Q) + where + Q: Copy + + PartialOrd + + PartialEq + + std::ops::Add + + std::ops::Rem + + std::ops::Sub + + constraint_enforcement::Abs + + std::fmt::Debug, + TEnforcer: ConstraintEnforcer + Default, + { + if let Some(constraint) = constraint { + constraint.apply_to::(state); + constraint.check(*state); + } + } + + pub fn apply_to(&self, state: &mut AircraftState) + where + TEnforcer: ConstraintEnforcer + + ConstraintEnforcer + + ConstraintEnforcer + + Default, + { + Self::apply::(&self.altitude, &mut state.altitude); + Self::apply::(&self.altitude_ground, &mut state.altitude_ground); + Self::apply::(&self.climb_rate, &mut state.climb_rate); + Self::apply::(&self.speed_air, &mut state.speed_air); + Self::apply::(&self.heading, &mut state.heading); + Self::apply::(&self.pitch, &mut state.pitch); + Self::apply::(&self.roll, &mut state.roll); + + state.steep_approach = self.steep_approach; + state.precision_approach = self.precision_approach; + state.go_around = self.go_around; + state.take_off = self.take_off; + } + + pub fn add_altitude_constraint(&mut self, c: Constraint) { + self.altitude = match &self.altitude { + Some(altitude) => Some(altitude.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_altitude_ground_constraint(&mut self, c: Constraint) { + self.altitude_ground = match &self.altitude_ground { + Some(altitude_gnd) => Some(altitude_gnd.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_climb_rate_constraint(&mut self, c: Constraint) { + self.climb_rate = match &self.climb_rate { + Some(climb_rate) => Some(climb_rate.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_speed_air_constraint(&mut self, c: Constraint) { + self.speed_air = match &self.speed_air { + Some(speed_air) => Some(speed_air.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_heading_constraint(&mut self, c: Constraint) { + self.heading = match &self.heading { + Some(heading) => Some(heading.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_pitch_constraint(&mut self, c: Constraint) { + self.pitch = match &self.pitch { + Some(pitch) => Some(pitch.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_roll_constraint(&mut self, c: Constraint) { + self.roll = match &self.roll { + Some(roll) => Some(roll.merge(&c).unwrap()), + None => Some(c), + } + } + + pub fn add_steep_approach_constraint(&mut self, c: bool) { + self.steep_approach = c; + } + + pub fn add_precision_approach_constraint(&mut self, c: bool) { + self.precision_approach = c; + } + + pub fn add_go_around_constraint(&mut self, c: bool) { + self.go_around = c; + } + + pub fn add_take_off_constraint(&mut self, c: bool) { + self.take_off = c; + } +} diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index 2adb97a..fe593e5 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -16,11 +16,11 @@ where + constraint_enforcement::Abs + std::fmt::Debug, { - AtLeast(usize, Q), - AtMost(usize, Q), - Equal(usize, Q), - InRange(usize, Q, Q), - NotInRange(usize, Q, Q), + AtLeast(Q), + AtMost(Q), + Equal(Q), + InRange(Q, Q), + NotInRange(Q, Q), } impl Constraint @@ -34,13 +34,93 @@ where + constraint_enforcement::Abs + std::fmt::Debug, { - pub fn phase(&self) -> usize { + fn normalize(&self) -> Constraint { match self { - Constraint::AtLeast(i, _) => *i, - Constraint::AtMost(i, _) => *i, - Constraint::Equal(i, _) => *i, - Constraint::InRange(i, _, _) => *i, - Constraint::NotInRange(i, _, _) => *i, + Constraint::AtLeast(l) => Constraint::AtLeast(*l), + Constraint::AtMost(r) => Constraint::AtMost(*r), + Constraint::Equal(x) => Constraint::Equal(*x), + Constraint::InRange(l, r) => { + let (l, r) = if l <= r { (l, r) } else { (r, l) }; + Constraint::InRange(*l, *r) + } + Constraint::NotInRange(l, r) => { + let (l, r) = if r <= l { (l, r) } else { (r, l) }; + Constraint::NotInRange(*l, *r) + } + } + } + + pub fn merge(&self, other: &Constraint) -> Result, String> { + let c1 = self.normalize(); + let c2 = other.normalize(); + match (c1, c2) { + (Constraint::AtLeast(l1), Constraint::AtLeast(l2)) => { + let l = if l1 >= l2 { l1 } else { l2 }; + Ok(Constraint::AtLeast(l)) + } + + (Constraint::AtMost(r1), Constraint::AtMost(r2)) => { + let r = if r1 <= r2 { r1 } else { r2 }; + Ok(Constraint::AtMost(r)) + } + + (Constraint::AtLeast(l), Constraint::AtMost(r)) + | (Constraint::AtMost(r), Constraint::AtLeast(l)) => match (l, r) { + (l, r) if l > r => Err(format!("unsatisfiable")), + (l, r) => Ok(Constraint::InRange(l, r)), + }, + + (Constraint::Equal(x), Constraint::AtLeast(l)) + | (Constraint::AtLeast(l), Constraint::Equal(x)) => match (x, l) { + (x, l) if x >= l => Ok(Constraint::Equal(x)), + _ => Err(format!("unsatisfiable")), + }, + + (Constraint::Equal(x), Constraint::AtMost(r)) + | (Constraint::AtMost(r), Constraint::Equal(x)) => match (x, r) { + (x, r) if x <= r => Ok(Constraint::Equal(x)), + _ => Err(format!("unsatisfiable")), + }, + + (Constraint::Equal(x), Constraint::Equal(y)) => match (x, y) { + (x, y) if x == y => Ok(Constraint::Equal(x)), + _ => Err(format!("unsatisfiable")), + }, + + (Constraint::AtLeast(l1), Constraint::InRange(l, r)) + | (Constraint::InRange(l, r), Constraint::AtLeast(l1)) => { + let at_least = Constraint::AtLeast(l1); + let range_least = Constraint::AtLeast(l); + let range_most = Constraint::AtMost(r); + at_least.merge(&range_least)?.merge(&range_most) + } + + (Constraint::AtMost(r1), Constraint::InRange(l, r)) + | (Constraint::InRange(l, r), Constraint::AtMost(r1)) => { + let at_most = Constraint::AtMost(r1); + let range_least = Constraint::AtLeast(l); + let range_most = Constraint::AtMost(r); + at_most.merge(&range_most)?.merge(&range_least) + } + + (Constraint::Equal(x), Constraint::InRange(l, r)) + | (Constraint::InRange(l, r), Constraint::Equal(x)) => { + let equal = Constraint::Equal(x); + let range = (Constraint::AtLeast(l), Constraint::AtMost(r)); + let x1 = equal.merge(&range.0)?; + let x2 = equal.merge(&range.1)?; + x1.merge(&x2) + } + + (Constraint::InRange(l1, r1), Constraint::InRange(l2, r2)) => { + let range1 = (Constraint::AtLeast(l1), Constraint::AtMost(r1)); + let range2 = (Constraint::AtLeast(l2), Constraint::AtMost(r2)); + let at_least = range1.0.merge(&range2.0)?; + let at_most = range1.1.merge(&range2.1)?; + at_least.merge(&at_most) + } + + _ => Err(format!("not supported")), } } @@ -51,41 +131,41 @@ where let mut bouncer = TEnforcer::default(); match self { - Constraint::AtLeast(_, l) => bouncer.at_least(quantity, *l), - Constraint::AtMost(_, l) => bouncer.at_most(quantity, *l), - Constraint::Equal(_, l) => *quantity = *l, - Constraint::InRange(_, l, r) => bouncer.in_range(quantity, *l, *r), - Constraint::NotInRange(_, l, r) => bouncer.not_in_range(quantity, *l, *r), + Constraint::AtLeast(l) => bouncer.at_least(quantity, *l), + Constraint::AtMost(l) => bouncer.at_most(quantity, *l), + Constraint::Equal(l) => *quantity = *l, + Constraint::InRange(l, r) => bouncer.in_range(quantity, *l, *r), + Constraint::NotInRange(l, r) => bouncer.not_in_range(quantity, *l, *r), } } pub fn check(&self, to_check: Q) { match self { - Constraint::AtLeast(_, l) => assert!( + Constraint::AtLeast(l) => assert!( to_check >= *l, "Checked Number {:?} failed constraint: at least {:?}", to_check, l ), - Constraint::AtMost(_, l) => assert!( + Constraint::AtMost(l) => assert!( to_check <= *l, "Checked Number {:?} failed constraint: at most {:?}", to_check, l ), - Constraint::Equal(_, l) => assert_eq!( + Constraint::Equal(l) => assert_eq!( &to_check, l, "Checked Number {:?} failed constraint: equal to {:?}", to_check, l ), - Constraint::InRange(_, l, r) => assert!( + Constraint::InRange(l, r) => assert!( to_check >= *l && to_check <= *r, "Checked Number {:?} failed constraint: in range {:?} - {:?}", to_check, l, r ), - Constraint::NotInRange(_, l, r) => assert!( + Constraint::NotInRange(l, r) => assert!( *l < to_check || to_check < *r, "Checked Number {:?} failed constraint: not in range {:?} - {:?}", to_check, diff --git a/taws_minimal/tests/util/constraints/mod.rs b/taws_minimal/tests/util/constraints/mod.rs index 7ffb39b..0f87fe7 100644 --- a/taws_minimal/tests/util/constraints/mod.rs +++ b/taws_minimal/tests/util/constraints/mod.rs @@ -1,9 +1,9 @@ -mod aircraft_state_constraint; +mod aircraft_state_constraints; mod airport_database; mod constraint; mod constraint_enforcement; -pub use aircraft_state_constraint::*; +pub use aircraft_state_constraints::*; pub use airport_database::*; pub use constraint::*; pub use constraint_enforcement::*; diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs index 547c39b..c6ba4af 100644 --- a/taws_minimal/tests/util/parameters.rs +++ b/taws_minimal/tests/util/parameters.rs @@ -130,20 +130,20 @@ impl FromStr for ConstraintParameter { match typ { "at least" => match q2 { Some(_) => Err(format!("unexpected: {}", s)), - None => Ok(Self(Constraint::AtLeast(0, q1))), + None => Ok(Self(Constraint::AtLeast(q1))), }, "at most" | "within" => match q2 { Some(_) => Err(format!("unexpected: {}", s)), - None => Ok(Self(Constraint::AtMost(0, q1))), + None => Ok(Self(Constraint::AtMost(q1))), }, "between" => match q2 { - Some(q2) if q1 <= q2 => Ok(Self(Constraint::InRange(0, q1, q2))), - Some(q2) => Ok(Self(Constraint::InRange(0, q2, q1))), + Some(q2) if q1 <= q2 => Ok(Self(Constraint::InRange(q1, q2))), + Some(q2) => Ok(Self(Constraint::InRange(q2, q1))), None => Err(format!("missing second bound: {}", s)), }, "not between" => match q2 { - Some(q2) if q1 <= q2 => Ok(Self(Constraint::NotInRange(0, q1, q2))), - Some(q2) => Ok(Self(Constraint::NotInRange(0, q2, q1))), + Some(q2) if q1 <= q2 => Ok(Self(Constraint::NotInRange(q1, q2))), + Some(q2) => Ok(Self(Constraint::NotInRange(q2, q1))), None => Err(format!("missing second bound: {}", s)), }, _ => Err(format!("invalid constraint type: {}", s)), From ee60b851990c7b9c04f1bf6a9b4b1018f0d82676 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 5 Sep 2022 14:39:05 +0200 Subject: [PATCH 31/73] fix(integration tests): implement phases --- taws_minimal/features/ffac.feature | 2 + taws_minimal/tests/cucumber.rs | 71 ++++++++++++++---------------- taws_minimal/tests/util/world.rs | 13 ++++-- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/taws_minimal/features/ffac.feature b/taws_minimal/features/ffac.feature index 3f0f25d..e54b490 100644 --- a/taws_minimal/features/ffac.feature +++ b/taws_minimal/features/ffac.feature @@ -15,6 +15,7 @@ Each of these additional categories of callouts is not required. And FFAC is not inhibited And non-precision approach is selected And the height above terrain is at least 500 foot + Given in the next phase When the height above terrain is at most 500 foot Then a FFAC annunciation alert is emitted within 1.3 seconds @@ -24,5 +25,6 @@ Each of these additional categories of callouts is not required. And FFAC is not inhibited And non-precision approach is selected And the nearest runway elevation is at least 500 foot + Given in the next phase When the nearest runway elevation is at most 500 foot Then a FFAC annunciation alert is emitted within 1.3 seconds diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 6358226..1b546f8 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -21,6 +21,11 @@ fn main() { // TODO allow for statefull tests // TODO evaluate merge possibilities re parser functions for similar sentences +#[given(expr = "in the next phase")] +fn given_new_phase(world: &mut MyWorld) { + world.next_phase(); +} + #[given(expr = "the plane {maybe} flying")] fn given_flying(_world: &mut MyWorld, _maybe: MaybeParameter) {} @@ -44,23 +49,23 @@ fn given_alert_inhibited(world: &mut MyWorld, alert: AlertParameter, maybe: Mayb #[given(expr = "steep approach {maybe} selected")] fn given_steep_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { - world.constraints[world.phase].add_steep_approach_constraint(maybe.into()); + world.phases[world.phase].add_steep_approach_constraint(maybe.into()); } #[given(expr = "non-precision approach {maybe} selected")] fn given_precision_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { let maybe: bool = maybe.into(); - world.constraints[world.phase].add_precision_approach_constraint(!maybe); + world.phases[world.phase].add_precision_approach_constraint(!maybe); } #[given(expr = "take-off {maybe} selected")] fn given_take_off(world: &mut MyWorld, maybe: MaybeParameter) { - world.constraints[world.phase].add_take_off_constraint(maybe.into()); + world.phases[world.phase].add_take_off_constraint(maybe.into()); } #[given(expr = "go around {maybe} selected")] fn given_go_around(world: &mut MyWorld, maybe: MaybeParameter) { - world.constraints[world.phase].add_go_around_constraint(maybe.into()); + world.phases[world.phase].add_go_around_constraint(maybe.into()); } #[given(expr = "the height above terrain is {constraint} foot")] @@ -77,7 +82,7 @@ fn given_height_above_terrain(world: &mut MyWorld, height_above_terrain: Constra Constraint::NotInRange(a, b) => Constraint::NotInRange(a * unit, b * unit), }; - world.constraints[world.phase].add_altitude_ground_constraint(height_above_terrain); + world.phases[world.phase].add_altitude_ground_constraint(height_above_terrain); } #[when(expr = "the rate of descent is {constraint} feet per minute")] @@ -93,7 +98,7 @@ fn when_rate_of_descent(world: &mut MyWorld, rate_of_descent: ConstraintParamete Constraint::NotInRange(a, b) => Constraint::NotInRange(b * unit, a * unit), }; - world.constraints[world.phase].add_climb_rate_constraint(climb_rate); + world.phases[world.phase].add_climb_rate_constraint(climb_rate); } #[when(expr = "the height above terrain is {constraint} feet")] @@ -109,7 +114,7 @@ fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: Constrain Constraint::NotInRange(a, b) => Constraint::NotInRange(a * unit, b * unit), }; - world.constraints[world.phase].add_altitude_ground_constraint(height_above_ground); + world.phases[world.phase].add_altitude_ground_constraint(height_above_ground); } #[then(expr = "{alert} {maybe} be armed")] @@ -117,55 +122,43 @@ fn then_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybePara assert_eq!(world.taws.is_armed(alert.into()), maybe.into()) } -#[then(expr = "a {alert} {alert_level} alert {maybe} emitted( at all)")] -fn then_alert_emitted( +#[then(expr = "a {alert} {alert_level} alert {maybe} emitted {constraint} seconds")] +fn then_alert_emitted_within( world: &mut MyWorld, alert: AlertParameter, level: AlertLevelParameter, should_emit: MaybeParameter, + _time: ConstraintParameter, ) { - let alert: Alert = alert.into(); - let level: AlertLevel = level.into(); - let should_emit: bool = should_emit.into(); - - let n_constraints = world.constraints.len(); - let aircraft_states = AircraftStateGenerator::default().take(world.test_length * n_constraints); - - for (c, mut frame) in aircraft_states - .enumerate() - .map(|(c, f)| (c % n_constraints, f)) - { - world.constraints[c].apply_to::(&mut frame); - - let alert_state = world.taws.process(&frame); - let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); - assert_eq!(emitted, should_emit); - } + then_alert_emitted(world, alert, level, should_emit) } -#[then(expr = "a {alert} {alert_level} alert {maybe} emitted {constraint} seconds")] -fn then_alert_emitted_within( +#[then(expr = "a {alert} {alert_level} alert {maybe} emitted( at all)")] +fn then_alert_emitted( world: &mut MyWorld, alert: AlertParameter, level: AlertLevelParameter, should_emit: MaybeParameter, - _time: ConstraintParameter, ) { let alert: Alert = alert.into(); let level: AlertLevel = level.into(); let should_emit: bool = should_emit.into(); - let n_constraints = world.constraints.len(); - let aircraft_states = AircraftStateGenerator::default().take(world.test_length * n_constraints); + let mut aircraft_states: Vec = AircraftStateGenerator::default() + .take(world.test_length) + .collect(); + + for (i, phase) in world.phases.iter().enumerate() { + for state in aircraft_states.iter_mut() { + phase.apply_to::(state); + let alert_state = world.taws.process(state); - for (c, mut frame) in aircraft_states - .enumerate() - .map(|(c, f)| (c % n_constraints, f)) - { - world.constraints[c].apply_to::(&mut frame); + if i < world.phases.len() - 1 { + continue; + } - let alert_state = world.taws.process(&frame); - let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); - assert_eq!(emitted, should_emit); + let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); + assert_eq!(emitted, should_emit); + } } } diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs index 145d65d..99ab22e 100644 --- a/taws_minimal/tests/util/world.rs +++ b/taws_minimal/tests/util/world.rs @@ -20,7 +20,7 @@ lazy_static::lazy_static! { #[derive(WorldInit)] pub struct MyWorld { pub taws: MinimalTaws<'static>, - pub constraints: Vec, + pub phases: Vec, pub test_length: usize, pub phase: usize, } @@ -32,8 +32,8 @@ impl cucumber::World for MyWorld { async fn new() -> Result { Ok(Self { taws: MinimalTaws::new(&TAWS_CONFIG), - constraints: vec![AircraftStateConstraints::default()], - test_length: 10, + phases: vec![AircraftStateConstraints::default()], + test_length: 1, phase: 0, }) } @@ -45,4 +45,11 @@ impl std::fmt::Debug for MyWorld { } } +impl MyWorld { + pub fn next_phase(&mut self) { + self.phases.push(AircraftStateConstraints::default()); + self.phase += 1; + } +} + impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? From 5ae6da55931e01c613d74f1824b0896a8a297e8c Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 5 Sep 2022 16:48:20 +0200 Subject: [PATCH 32/73] fix(Mode3): invalid envelope --- opentaws/src/alerts/mode_3.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentaws/src/alerts/mode_3.rs b/opentaws/src/alerts/mode_3.rs index 587104b..ee390dc 100644 --- a/opentaws/src/alerts/mode_3.rs +++ b/opentaws/src/alerts/mode_3.rs @@ -67,7 +67,7 @@ lazy_static::lazy_static! { static ref CAUTION_ENVELOPE_METHODE_2: Envelope<3> = Envelope::new([ (11.0, 35.0), (104.0, 1100.0), - (104.0, 1100.0), + (104.0001, 1100.0), ]) .unwrap(); } From e47a7dcb3058b2fcf0a9285bee094cfdb240e502 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 5 Sep 2022 16:50:24 +0200 Subject: [PATCH 33/73] fix(AircraftStateConstraints): make boolean constraints optional --- .../constraints/aircraft_state_constraints.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs index 67c841e..704a8bf 100644 --- a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs @@ -13,10 +13,10 @@ pub struct AircraftStateConstraints { pitch: Option>, roll: Option>, - steep_approach: bool, - precision_approach: bool, - go_around: bool, - take_off: bool, + steep_approach: Option, + precision_approach: Option, + go_around: Option, + take_off: Option, } impl AircraftStateConstraints { @@ -53,10 +53,10 @@ impl AircraftStateConstraints { Self::apply::(&self.pitch, &mut state.pitch); Self::apply::(&self.roll, &mut state.roll); - state.steep_approach = self.steep_approach; - state.precision_approach = self.precision_approach; - state.go_around = self.go_around; - state.take_off = self.take_off; + state.steep_approach = self.steep_approach.unwrap_or(state.steep_approach); + state.precision_approach = self.precision_approach.unwrap_or(state.precision_approach); + state.go_around = self.go_around.unwrap_or(state.go_around); + state.take_off = self.take_off.unwrap_or(state.take_off); } pub fn add_altitude_constraint(&mut self, c: Constraint) { @@ -109,18 +109,18 @@ impl AircraftStateConstraints { } pub fn add_steep_approach_constraint(&mut self, c: bool) { - self.steep_approach = c; + self.steep_approach = Some(c); } pub fn add_precision_approach_constraint(&mut self, c: bool) { - self.precision_approach = c; + self.precision_approach = Some(c); } pub fn add_go_around_constraint(&mut self, c: bool) { - self.go_around = c; + self.go_around = Some(c); } pub fn add_take_off_constraint(&mut self, c: bool) { - self.take_off = c; + self.take_off = Some(c); } } From b907d5b6da9abeb2fc081de924cbdb1cb3f06bd9 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 5 Sep 2022 16:51:00 +0200 Subject: [PATCH 34/73] fix(integration tests): impl then_alert_armed --- taws_minimal/tests/cucumber.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 1b546f8..f78734e 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -119,7 +119,14 @@ fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: Constrain #[then(expr = "{alert} {maybe} be armed")] fn then_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { - assert_eq!(world.taws.is_armed(alert.into()), maybe.into()) + let mut state = AircraftStateGenerator::default().next().unwrap(); + for phase in world.phases.iter() { + phase.apply_to::(&mut state); + let _alerts = world.taws.process(&state); + } + + let is_armed = world.taws.is_armed(alert.into()); + assert_eq!(is_armed, maybe.into()) } #[then(expr = "a {alert} {alert_level} alert {maybe} emitted {constraint} seconds")] From ee6fed96477cd39e66d186ef793680aa5e8833ca Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 6 Sep 2022 10:46:41 +0200 Subject: [PATCH 35/73] cleanup --- taws_minimal/tests/util/aircraft_state.rs | 2 +- .../tests/util/constraints/constraint.rs | 18 ++++++------- taws_minimal/tests/util/parameters.rs | 26 +++++++++---------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/taws_minimal/tests/util/aircraft_state.rs b/taws_minimal/tests/util/aircraft_state.rs index c1176db..e40d610 100644 --- a/taws_minimal/tests/util/aircraft_state.rs +++ b/taws_minimal/tests/util/aircraft_state.rs @@ -50,7 +50,7 @@ impl Iterator for AircraftStateGenerator { while buf.len() < bytes_needed { buf.extend_from_slice(&self.0.next_u64().to_le_bytes()); } - let mut u = Unstructured::new(&mut buf); + let mut u = Unstructured::new(&buf); Some(AircraftStateWrapper::arbitrary(&mut u).unwrap().0) // the unwrap is safe, we guarantee that enough bytes are available } diff --git a/taws_minimal/tests/util/constraints/constraint.rs b/taws_minimal/tests/util/constraints/constraint.rs index fe593e5..094881b 100644 --- a/taws_minimal/tests/util/constraints/constraint.rs +++ b/taws_minimal/tests/util/constraints/constraint.rs @@ -1,10 +1,6 @@ -use std::any::Any; - -use uom::num_traits::{Signed, Zero}; - use super::constraint_enforcement::{self, ConstraintEnforcer}; -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub enum Constraint where Q: Copy @@ -66,25 +62,25 @@ where (Constraint::AtLeast(l), Constraint::AtMost(r)) | (Constraint::AtMost(r), Constraint::AtLeast(l)) => match (l, r) { - (l, r) if l > r => Err(format!("unsatisfiable")), + (l, r) if l > r => Err("unsatisfiable".to_string()), (l, r) => Ok(Constraint::InRange(l, r)), }, (Constraint::Equal(x), Constraint::AtLeast(l)) | (Constraint::AtLeast(l), Constraint::Equal(x)) => match (x, l) { (x, l) if x >= l => Ok(Constraint::Equal(x)), - _ => Err(format!("unsatisfiable")), + _ => Err("unsatisfiable".to_string()), }, (Constraint::Equal(x), Constraint::AtMost(r)) | (Constraint::AtMost(r), Constraint::Equal(x)) => match (x, r) { (x, r) if x <= r => Ok(Constraint::Equal(x)), - _ => Err(format!("unsatisfiable")), + _ => Err("unsatisfiable".to_string()), }, (Constraint::Equal(x), Constraint::Equal(y)) => match (x, y) { (x, y) if x == y => Ok(Constraint::Equal(x)), - _ => Err(format!("unsatisfiable")), + _ => Err("unsatisfiable".to_string()), }, (Constraint::AtLeast(l1), Constraint::InRange(l, r)) @@ -120,7 +116,9 @@ where at_least.merge(&at_most) } - _ => Err(format!("not supported")), + // Merging NotInRange could lead to non convex constraints or constraints containing `Greater Than` or `Less Than` comparisons. + // Could be implemented, but maybe not worth it. + _ => Err("not supported".to_string()), } } diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs index c6ba4af..2db10e8 100644 --- a/taws_minimal/tests/util/parameters.rs +++ b/taws_minimal/tests/util/parameters.rs @@ -4,16 +4,14 @@ use cucumber::Parameter; use lazy_static::lazy_static; use opentaws::{Alert, AlertLevel}; use regex::Regex; -use uom::si::f64::Length; -use uom::si::length; use super::constraints::Constraint; pub struct MaybeParameter(bool); -impl Into for MaybeParameter { - fn into(self) -> bool { - self.0 +impl From for bool { + fn from(maybe_param: MaybeParameter) -> Self { + maybe_param.0 } } @@ -58,9 +56,9 @@ impl FromStr for AlertParameter { } } -impl Into for AlertParameter { - fn into(self) -> Alert { - self.0 +impl From for Alert { + fn from(alert_param: AlertParameter) -> Self { + alert_param.0 } } @@ -71,9 +69,9 @@ impl Parameter for AlertParameter { pub struct AlertLevelParameter(AlertLevel); -impl Into for AlertLevelParameter { - fn into(self) -> AlertLevel { - self.0 +impl From for AlertLevel { + fn from(alert_level_param: AlertLevelParameter) -> Self { + alert_level_param.0 } } @@ -151,9 +149,9 @@ impl FromStr for ConstraintParameter { } } -impl Into> for ConstraintParameter { - fn into(self) -> Constraint { - self.0 +impl From for Constraint { + fn from(constraint_param: ConstraintParameter) -> Self { + constraint_param.0 } } From 7b5d66cac514ffac36326bdee9646af7a6771bba Mon Sep 17 00:00:00 2001 From: wucke13 Date: Mon, 28 Nov 2022 14:09:05 +0100 Subject: [PATCH 36/73] fix staging build This primarily updates the lock files and moves the uom override to the workspace Cargo.toml --- where it belongs. --- Cargo.lock | 4 ++-- Cargo.toml | 5 +++++ aviation_database/Cargo.toml | 4 ++-- flake.lock | 41 ++++++++++++++++++------------------ opentaws/Cargo.toml | 3 +-- taws_minimal/Cargo.toml | 8 ++----- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 883585d..873fd26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2009,8 +2009,8 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "uom" -version = "0.32.0" -source = "git+https://github.com/wucke13/uom.git?branch=fix-missing-libm#d87446532affa55eecb697a227fcf09d0b02f55b" +version = "0.33.0" +source = "git+https://github.com/wucke13/uom?branch=fix-missing-libm#80c05d4848c29f5d356477f2a0636c6ad15160b8" dependencies = [ "num-traits", "serde", diff --git a/Cargo.toml b/Cargo.toml index c3f5b95..af319cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,8 @@ members = [ "kd_tree", "kd_tree_sort" ] + + +[patch.crates-io] +# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands +uom = { git = "https://github.com/wucke13/uom", branch = "fix-missing-libm" } \ No newline at end of file diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml index a5dff6c..3cec418 100644 --- a/aviation_database/Cargo.toml +++ b/aviation_database/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] ordered-float = { version = "2.0", default-features = false } -uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } +uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } kd_tree = { path = "../kd_tree" } @@ -21,6 +21,6 @@ regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uneval = "0.2" -uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } +uom = { version = "0", default-features = false, features = [ "f64", "si", "libm" ] } ureq = "2" kd_tree_sort = { path = "../kd_tree_sort" } diff --git a/flake.lock b/flake.lock index 55fba69..9312f71 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1654756015, - "narHash": "sha256-yTDkAPSUjcy8ADa6U9gP7IAVaZpEvtQt+BGHQ0v4KMA=", + "lastModified": 1669616799, + "narHash": "sha256-cTe0E41+4h3LS7NtYd+LdE2ngvIBZ5VIQflT4qu+z9I=", "ref": "main", - "rev": "fcf7d9029dab1c4a13aaee009feba7658f415add", - "revCount": 1062, + "rev": "864fe18d688b0c8c0730bb179b6686eac951f613", + "revCount": 1269, "type": "git", "url": "https://github.com/nix-community/fenix.git" }, @@ -29,11 +29,11 @@ ] }, "locked": { - "lastModified": 1654608517, - "narHash": "sha256-KIxHjDDJYhoiLanLjpeAk5AuZsfip8M62JhkuloEGb0=", - "ref": "master", - "rev": "14997a79cd78fe34ad6390f18a327ee0593e5eec", - "revCount": 300, + "lastModified": 1662220400, + "narHash": "sha256-9o2OGQqu4xyLZP9K6kNe1pTHnyPz0Wr3raGYnr9AIgY=", + "ref": "refs/heads/master", + "rev": "6944160c19cb591eb85bbf9b2f2768a935623ed3", + "revCount": 305, "type": "git", "url": "https://github.com/nix-community/naersk.git" }, @@ -44,9 +44,10 @@ }, "nixpkgs": { "locked": { - "lastModified": 0, - "narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=", - "path": "/nix/store/ny7x54058ki7k1d3ny0jx5h6kw926mxv-source", + "lastModified": 1669289248, + "narHash": "sha256-+ErmUe0ph4nJL2C+xwuIt2TR95fvGDy64jEtism5wps=", + "path": "/nix/store/fiapm3lr62f4fyyxhy45qzcz8flxcvf0-source", + "rev": "73463c394af9fed20f3ce8cd491bf7c8271d20d8", "type": "path" }, "original": { @@ -65,11 +66,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1654700117, - "narHash": "sha256-x3rF4IMwZUYnwF3JUnJvtIJmixrYkrl74K9EjhJMSr8=", + "lastModified": 1669551522, + "narHash": "sha256-ScH3I2/5+tCN23U8mUUj/HoZXDF11fo1z93X9imAfOo=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "79a4a464b07d626de17bd4b5f2382b5634644f7d", + "rev": "6d61be8e65ac0fd45eaf178e1f7a1ec6b582de1f", "type": "github" }, "original": { @@ -81,11 +82,11 @@ }, "utils": { "locked": { - "lastModified": 1653893745, - "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=", - "ref": "master", - "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1", - "revCount": 58, + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "ref": "refs/heads/master", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "revCount": 66, "type": "git", "url": "https://github.com/numtide/flake-utils.git" }, diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 553c97e..bd0bfa2 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -29,8 +29,7 @@ use-serde = ["uom/use_serde"] aviation_database = { path = "../aviation_database"} lazy_static = { version = "1", features = [ "spin_no_std" ] } -# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands -uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", "libm" ] } +uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } ringbuffer = "0.8" serde = { version = "1.0", default-features = false, features = [ "derive" ] } serde_arrays = "*" # Serde const generic "workaround" diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index 27948d9..b1810f8 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -26,12 +26,8 @@ opentaws = { path = "../opentaws" } aviation_database = { path = "../aviation_database" } -# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands -uom = { git = "https://github.com/wucke13/uom.git", branch = "fix-missing-libm", default-features = false, features = [ - "f64", - "si", - "libm", -] } + +uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } casey = "0.3" serde = { version = "1.0", default-features = false, features = ["derive"] } From 0fbd15754be4fdbe2e9bf730d7ef1f55a26ff43e Mon Sep 17 00:00:00 2001 From: wucke13 Date: Mon, 28 Nov 2022 14:37:03 +0100 Subject: [PATCH 37/73] update github actions workflow --- .github/workflows/rust.yml | 53 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6ca219d..2d9fb43 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,17 +10,12 @@ jobs: format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: stable components: rustfmt override: true - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: x86_64-unknown-linux-gnu - override: true - name: Run tests run: cargo fmt -- --check @@ -28,33 +23,37 @@ jobs: runs-on: ubuntu-latest continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name == 'staging' }} steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: stable target: x86_64-unknown-linux-gnu override: true - name: Run tests - run: cargo test --all-features --verbose + run: cargo test --all-features --verbose clippy_check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v1 + - uses: actions/cache@v3 with: path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }} + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - uses: actions-rs/toolchain@v1 with: toolchain: nightly @@ -73,14 +72,16 @@ jobs: image: xd009642/tarpaulin:latest options: --security-opt seccomp=unconfined steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-tarpaulin-${{ hashFiles('**/Cargo.lock') }} + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - uses: actions-rs/toolchain@v1 with: toolchain: nightly From a61ab97be157009297b9217946b596bc44408823 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 12 Sep 2022 15:13:48 +0200 Subject: [PATCH 38/73] fix --- taws_minimal/tests/cucumber.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index f78734e..bc080ec 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -155,8 +155,8 @@ fn then_alert_emitted( .take(world.test_length) .collect(); - for (i, phase) in world.phases.iter().enumerate() { - for state in aircraft_states.iter_mut() { + for state in aircraft_states.iter_mut() { + for (i, phase) in world.phases.iter().enumerate() { phase.apply_to::(state); let alert_state = world.taws.process(state); From 6908266af628fd3fba067cf31480ed184735b659 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 13 Sep 2022 19:21:29 +0200 Subject: [PATCH 39/73] fix --- taws_minimal/tests/util/world.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs index 99ab22e..85545e6 100644 --- a/taws_minimal/tests/util/world.rs +++ b/taws_minimal/tests/util/world.rs @@ -33,7 +33,7 @@ impl cucumber::World for MyWorld { Ok(Self { taws: MinimalTaws::new(&TAWS_CONFIG), phases: vec![AircraftStateConstraints::default()], - test_length: 1, + test_length: 10, phase: 0, }) } From d22ac891ef4b254a9bc3dbb0cd0a38eb383dd155 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 22 Sep 2022 04:11:59 +0200 Subject: [PATCH 40/73] revises PDA cucumber feature --- taws_minimal/features/pda.feature | 94 +++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 29 deletions(-) diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature index 2cebcaa..750aa09 100644 --- a/taws_minimal/features/pda.feature +++ b/taws_minimal/features/pda.feature @@ -1,38 +1,74 @@ -#noinspection CucumberUndefinedStep -Feature: PDA: Premature Decent Alerting - # TODO: Description +@DO_367 @CLASS_C @PDA +Feature: Premature Descent Alerting (PDA) + The PDA functionality monitors the final approach and + alerts the crew if the aircraft is about to crash into the ground short of the runway. + Detection of these conditions is based upon height above runway elevation or + height above terrain/obstacles and distance to runway. - @MOPS_263 - Scenario: Mode Arming/Disarming - Given the plane is within 5 NM of an airport + Background: + Given the aircraft is in the landing flight segment + + @ARMING_DISARMING @MOPS_263 + Scenario: Class C Equipment shall arm PDA within 5 NM of an airport. + Given the distance to the nearest airport is less than 5 NM Then PDA shall be armed - # TODO Add Criteria for PDA to be disarmed beyond 5 NM due to the risk of nuisance alerts (2.2.3.1.7.2) + Rule: PDA is armed and not inhibited + + Background: + Given PDA is not inhibited + + @ALERT_CRITERIA + Scenario: Class C Equipment should not generate PDA alerts for normal visual flight rules (VFR) operations in the airport area. + Given the distance to the nearest airport is less than 5 NM + When the height above terrain is at least 800 feet + Then a PDA alert is no emitted + + @ALERT_CRITERIA + Scenario: Airplanes routinely operate in VFR conditions ... within 10-15 NM of the nearest airport, ... should not generate alerts ... + Given the distance to the nearest airport is less than 10 NM + When the height above terrain is at least 1000 feet + Then a PDA alert is no emitted + + @ALERT_CRITERIA + Scenario: Airplanes routinely operate in the visual segment of a circling approach ... should not generate PDA alerts ... + Given the distance to the nearest airport is less than 2 NM + And circling approach is selected + When the height above terrain is at least 300 feet + Then a PDA alert is no emitted + + @ALERT_CRITERIA @CAUTION @MOPS_264 + Scenario Outline: Class C Equipment shall provide a caution alert when ... + When the distance to runway is between and NM + And the height above terrain is between 10.0 and feet + Then a PDA caution alert is emitted within 1.3 seconds + + Examples: + | min_distance_runway | max_distance_runway | max_height_ground | + | 1.0 | 1.8 | 80.0 | + | 1.81 | 2.3 | 150.0 | + | 2.31 | 5.0 | 170.0 | - @MOPS_264 - Scenario Outline: Must Alert - Given PDA is armed - And PDA is not inhibited - When the distance to the nearest airport is between 1.0 and NM - And the height above terrain is between 10 and feet - Then a PDA caution alert is emitted within 1.3 seconds + Rule: PDA is not-armed or inhibited - Examples: - | distance_to_airport | height | - | 1.0 | 80 | - | 1.8 | 150 | - | 2.3 | 170 | + @ALERT_CRITERIA @CAUTION @MOPS_265 + Scenario: Class C Equipment shall not provide a PDA caution alert when ... PDA is not armed. + When the distance to the nearest airport is at least 5.1 NM + And the height above terrain is between 10.0 and 170.0 feet + Then PDA is not armed + And a PDA caution is not emitted - @MOPS_265 - Scenario: Must Not Alert when not Armed - Given PDA is not armed - Then a PDA caution alert is not emitted at all + @ALERT_CRITERIA @CAUTION @MOPS_265 + Scenario: Class C Equipment shall not provide a PDA caution alert when ... PDA is inhibited. + Given PDA is inhibited + When the distance to runway is 1.0 NM + And the height above terrain is 10.0 feet + Then a PDA caution is no emitted - @MOPS_265 - Scenario: Must Not Alert when Inhibited - Given PDA is inhibited - Then a PDA caution alert is not emitted at all + Rule: PDA is armed and not-inhibited and an alert is active - # MOPS_266 and MOPS_267 are not testable + @AURAL_ALERT @CAUTION @MOPS_266 + Scenario: Class C Equipment shall be capable of generating or triggering an aural message of at least one of “Too Low” and “Too Low Terrain”. -# vim: set ts=2 sw=2 expandtab: retab: expandtab # + @VISUAL_ALERT @CAUTION @MOPS_267 + Scenario: Class C Equipment shall be capable of providing an output to trigger a yellow or amber indication. From ba562e73f7e8c4a7e059beb9d3d3e9d4fd4d8132 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 22 Sep 2022 13:22:17 +0200 Subject: [PATCH 41/73] revises Mode1 cucumber feature --- taws_minimal/features/mode_1.feature | 422 +++++++++++++-------------- 1 file changed, 202 insertions(+), 220 deletions(-) diff --git a/taws_minimal/features/mode_1.feature b/taws_minimal/features/mode_1.feature index 3899bce..105bf97 100644 --- a/taws_minimal/features/mode_1.feature +++ b/taws_minimal/features/mode_1.feature @@ -1,222 +1,204 @@ -#noinspection CucumberUndefinedStep -Feature: Mode 1: Excessive Rate of Descent - The Mode 1 alert is intended to generate caution alerts and time-critical - warning alerts when the aircraft has a high rate of descent relative to its - height above terrain. Mode 1 is active during all segments of flight. In - order to reduce nuisance alerts during steep approaches, an optional set of - alerting curves may be employed when the aircraft is performing a steep - approach. The determination if a steep approach is in progress can either be - based on an input to the Equipment (such as a pilot-activated steep approach - switch) or it can be based on internal logic (such as comparison of aircraft - position to approach profiles in a database). - - @MOPS_268 - Scenario: Mode Arming/Disarming - Given the plane is flying +@DO_367 @CLASS_C @MODE_1 +Feature: Excessive Rate of Descent (Mode 1) + The Mode 1 alert is intended to generate caution alerts and time-critical warning alerts + when the aircraft has a high rate of descent relative to its height above terrain. Mode 1 is + active during all segments of flight. + + @ARMING_DISARMING @MOPS_268 + Scenario: Class C Equipment shall arm Mode 1 during the entire flight. Then Mode 1 shall be armed - #Rule: Standard Caution Envelope (MOPS_269, MOPS_270) - - @MOPS_269 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is not selected - When the rate of descent is at least feet per minute - And the height above terrain is between 100 and feet - Then a Mode 1 caution alert is emitted within 2 seconds - - Examples: - | rate_of_descent | height | - | 1560 | 100 | - | 2200 | 630 | - | 5700 | 2200 | - - @MOPS_270 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 caution alert is not emitted at all - - @MOPS_270 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 caution alert is not emitted at all - - @MOPS_270 - Scenario Outline: Must Not Alert - Given steep approach is not selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 caution alert is not emitted at all - - Examples: - | rate_of_descent | height | - | 964 | 10 | - | 2300 | 1550 | - | 4400 | 2900 | - | 5000 | 3200 | - | 8000 | 4600 | - | 12000 | 6467 | - - #Rule: Steep Approach Caution Envelope (MOPS_271, MOPS_272) - - @MOPS_271 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is selected - When the rate of descent is at least feet per minute - And the height above terrain is between 150 and feet - Then a Mode 1 caution alert is emitted within 2 seconds - - Examples: - | rate_of_descent | height | - | 1798 | 150 | - | 1944 | 300 | - | 3233 | 1078 | - | 6225 | 2075 | - - @MOPS_272 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 caution alert is not emitted at all - - @MOPS_272 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 caution alert is not emitted at all - - @MOPS_272 - Scenario Outline: Must Not Alert - Given steep approach is selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 caution alert is not emitted at all - - Examples: - | rate_of_descent | height | - | 964 | 10 | - | 2300 | 1550 | - | 4400 | 2900 | - | 5000 | 3200 | - | 8000 | 4600 | - | 12000 | 6467 | - - #Rule: Warning Envelope (MOPS_273, MOPS_274) - - @MOPS_273 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is not selected - When the rate of descent is at least feet per minute - And the height above terrain is between 100 and feet - Then a Mode 1 warning alert is emitted within 2 seconds - - Examples: - | rate_of_descent | height | - | 1600 | 100 | - | 1850 | 300 | - | 10100 | 1958 | - - @MOPS_274 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 warning alert is not emitted at all - - @MOPS_274 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 warning alert is not emitted at all - - @MOPS_274 - Scenario Outline: Must Not Alert - Given steep approach is not selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 warning alert is not emitted at all - - Examples: - | rate_of_descent | height | - | 1217 | 10 | - | 2300 | 1300 | - | 4400 | 2500 | - | 8000 | 3500 | - | 12000 | 4611 | - - #Rule: Steep Approach Warning Envelope (MOPS_275, MOPS_276) - - @MOPS_275 - Scenario Outline: Must Alert - Given Mode 1 is armed - And Mode 1 is not inhibited - And steep approach is selected - When the rate of descent is at least feet per minute - And the height above terrain is between 150 and feet - Then a Mode 1 warning alert is emitted within 2 seconds - - Examples: - | rate_of_descent | height | - | 1908 | 150 | - | 2050 | 300 | - | 10300 | 1958 | - - @MOPS_276 - Scenario: Must Not Alert when not Armed - Given Mode 1 is not armed - Then a Mode 1 warning alert is not emitted at all - - @MOPS_276 - Scenario: Must Not Alert when Inhibited - Given Mode 1 is inhibited - Then a Mode 1 warning alert is not emitted at all - - @MOPS_276 - Scenario Outline: Must Not Alert - Given steep approach is selected - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 1 warning alert is not emitted at all - - Examples: - | rate_of_descent | height | - | 1217 | 10 | - | 2300 | 1300 | - | 4400 | 2500 | - | 8000 | 3500 | - | 12000 | 4611 | - - #Rule: Aural Alert (MOPS_277, MOPS_278, MOPS_279, MOPS_280) - - @MOPS_277 - Scenario: Caution Alert - Given a caution level Mode 1 alert arises - Then an aural message "Sink Rate" shall be emitted - - @MOPS_278 - Scenario: Warning Alert - Given a warning level Mode 1 alert arises - Then an aural message "Pull Up" shall be emitted - - @MOPS_279 - Scenario: Repeating Warning Alert - Given the warning level Mode 1 alert condition persists - And the pilot didn't silence the alert - And no higher priority alert is triggered - Then the aural message shall be repeated periodically - - # Whoop-Whoop (MOPS_280) ain't gonna be testable - - #Rule: Visual Alert (MOPS_281, MOPS_282) - - @MOPS_281 - Scenario: Caution - Given a Mode 1 caution alert is active - Then the TAWS shall trigger a yellow or amber indicator - - @MOPS_282 - Scenario: Warning - Given a Mode 1 warning alert is active - Then the TAWS shall trigger a red indicator - -# vim: set ts=2 sw=2 expandtab: retab: expandtab # + Rule: Standard Caution Envelope + + Background: + Given steep approach is not selected + + @ALERT_CRITERIA @CAUTION @MOPS_269 + Scenario Outline: Class C Equipment shall provide a caution alert when ... + Given Mode 1 is not inhibited + When the rate of descent is at least feet per minute + When the height above terrain is between 100.0 and feet + Then a Mode 1 caution shall be emitted within 2.0 seconds + + Examples: + | min_rate_descent | max_height_terrain | + | 1560.0 | 100.0 | + | 2200.0 | 630.0 | + | 5700.0 | 2200.0 | + + @ALERT_CRITERIA @CAUTION @MOPS_270 + Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is not armed. + + @ALERT_CRITERIA @CAUTION @MOPS_270 + Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. + Given Mode 1 is inhibited + When the rate of descent is 1560.0 feet per minute + When the height above terrain is 100.0 feet + Then a Mode 1 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_270 + Scenario Outline: Class C Equipment shall not provide a Mode 1 caution alert when ... within the Must Not Alert envelope ... + Given Mode 1 is not inhibited + When the rate of descent is at most feet per minute + When the height above terrain is at least feet + Then a Mode 1 caution shall not be emitted + + Examples: + | max_rate_descent | min_height_terrain | + | 963.9 | 10.0 | + | 2299.9 | 1550.0 | + | 4399.9 | 2900.0 | + | 4999.9 | 3200.0 | + | 7999.9 | 4600.0 | + | 11999.9 | 6467.0 | + + Rule: Steep Approach Caution Envelope + + Background: + Given steep approach is selected + + @ALERT_CRITERIA @CAUTION @MOPS_271 + Scenario Outline: Class C Equipment shall provide a caution alert when ... + Given Mode 1 is not inhibited + When the rate of descent is at least feet per minute + When the height above terrain is between 150.0 and feet + Then a Mode 1 caution shall be emitted within 2.0 seconds + + Examples: + | min_rate_descent | max_height_terrain | + | 1798.0 | 150.0 | + | 1944.0 | 300.0 | + | 3233.0 | 1078.0 | + | 6225.0 | 2075.0 | + + @ALERT_CRITERIA @CAUTION @MOPS_272 + Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is not armed. + + @ALERT_CRITERIA @CAUTION @MOPS_272 + Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. + Given Mode 1 is inhibited + When the rate of descent is 1798.0 feet per minute + When the height above terrain 150.0 feet + Then a Mode 1 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_272 + Scenario Outline: Class C Equipment shall not provide a Mode 1 caution alert when ... within the Must Not Alert envelope ... + Given Mode 1 is not inhibited + When the rate of descent is at most feet per minute + When the height above terrain is at least feet + Then a Mode 1 caution shall not be emitted + + Examples: + | max_rate_descent | min_height_terrain | + | 963.9 | 10.0 | + | 2299.9 | 1550.0 | + | 4399.9 | 2900.0 | + | 4999.9 | 3200.0 | + | 7999.9 | 4600.0 | + | 11999.9 | 6467.0 | + + Rule: Standard Warning Envelope + + Background: + Given steep approach is not selected + + @ALERT_CRITERIA @WARNING @MOPS_273 + Scenario Outline: Class C Equipment shall provide a warning alert when ... + Given Mode 1 is not inhibited + When the rate of descent is at least feet per minute + When the height above terrain is between 100.0 and feet + Then a Mode 1 warning shall be emitted within 2.0 seconds + + Examples: + | min_rate_descent | max_height_terrain | + | 1600.0 | 100.0 | + | 1850.0 | 300.0 | + | 10100.0 | 1958.0 | + + @ALERT_CRITERIA @WARNING @MOPS_274 + Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is not armed. + + @ALERT_CRITERIA @WARNING @MOPS_274 + Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. + Given Mode 1 is inhibited + When the rate of descent is 1600.0 feet per minute + When the height above terrain is 100.0 feet + Then a Mode 1 warning shall not be emitted + + @ALERT_CRITERIA @WARNING @MOPS_274 + Scenario Outline: Class C Equipment shall not provide a Mode 1 warning alert when ... within the Must Not Alert envelope ... + Given Mode 1 is not inhibited + When the rate of descent is at most feet per minute + When the height above terrain is at least feet + Then a Mode 1 warning shall not be emitted + + Examples: + | max_rate_descent | min_height_terrain | + | 1216.9 | 10.0 | + | 2299.9 | 1300.0 | + | 4399.9 | 2500.0 | + | 7999.9 | 3500.0 | + | 11999.9 | 4611.0 | + + Rule: Steep Approach Warning Envelope + + Background: + Given steep approach is selected + + @ALERT_CRITERIA @WARNING @MOPS_275 + Scenario Outline: Class C Equipment shall provide a warning alert when ... + Given Mode 1 is not inhibited + When the rate of descent is at least feet per minute + When the height above terrain is between 150.0 and feet + Then a Mode 1 warning shall be emitted within 2.0 seconds + + Examples: + | min_rate_descent | max_height_terrain | + | 1908.0 | 150.0 | + | 2050.0 | 300.0 | + | 10300.0 | 1958.0 | + + @ALERT_CRITERIA @WARNING @MOPS_276 + Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is not armed. + + @ALERT_CRITERIA @WARNING @MOPS_276 + Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. + Given Mode 1 is inhibited + When the rate of descent is 1908.0 feet per minute + When the height above terrain is 150.0 feet + Then a Mode 1 warning shall not be emitted + + @ALERT_CRITERIA @WARNING @MOPS_276 + Scenario Outline: Class C Equipment shall not provide a Mode 1 warning alert when ... within the Must Not Alert envelope ... + Given Mode 1 is not inhibited + When the rate of descent is at most feet per minute + When the height above terrain is at least feet + Then a Mode 1 warning shall not be emitted + + Examples: + | max_rate_descent | min_height_terrain | + | 1216.9 | 10.0 | + | 2299.9 | 1300.0 | + | 4399.9 | 2500.0 | + | 7999.9 | 3500.0 | + | 11999.9 | 4611.0 | + + Rule: Mode 1 is armed and not-inhibited and an alert is active + + @AURAL_ALERT @CAUTION @MOPS_277 + Scenario: Class C Equipment shall be capable of generating or triggering an aural message of “Sink Rate”. + + @AURAL_ALERT @WARNING @MOPS_278 + Scenario: Class C Equipment shall be capable of generating or triggering an aural message of “Pull up”. + + @AURAL_ALERT @WARNING @MOPS_279 + Scenario: Class C Equipment shall repeat the aural message periodically for the duration of the Mode 1 warning alert condition, or until silenced by the pilot or a higher priority alert. + + @AURAL_ALERT @WARNING @MOPS_280 + Scenario: Class C Equipment shall generate a tone sweep ... + + @VISUAL_ALERT @CAUTION @MOPS_281 + Scenario: Class C Equipment shall be capable of providing an output to trigger a yellow or amber indication. + + @VISUAL_ALERT @WARNING @MOPS_282 + Scenario: Class C Equipment shall be capable of providing an output to trigger a red indication. From 35698afd7ed0f7267c2bbb04df27a7cee90942b9 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 22 Sep 2022 19:51:25 +0200 Subject: [PATCH 42/73] fix --- taws_minimal/features/mode_1.feature | 10 ++++++++++ taws_minimal/features/pda.feature | 2 ++ 2 files changed, 12 insertions(+) diff --git a/taws_minimal/features/mode_1.feature b/taws_minimal/features/mode_1.feature index 105bf97..a5b4a78 100644 --- a/taws_minimal/features/mode_1.feature +++ b/taws_minimal/features/mode_1.feature @@ -28,6 +28,7 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @CAUTION @MOPS_270 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is not armed. + Given not implemented @ALERT_CRITERIA @CAUTION @MOPS_270 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. @@ -73,6 +74,7 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @CAUTION @MOPS_272 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is not armed. + Given not implemented @ALERT_CRITERIA @CAUTION @MOPS_272 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. @@ -117,6 +119,7 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @WARNING @MOPS_274 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is not armed. + Given not implemented @ALERT_CRITERIA @WARNING @MOPS_274 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. @@ -160,6 +163,7 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @WARNING @MOPS_276 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is not armed. + Given not implemented @ALERT_CRITERIA @WARNING @MOPS_276 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. @@ -187,18 +191,24 @@ Feature: Excessive Rate of Descent (Mode 1) @AURAL_ALERT @CAUTION @MOPS_277 Scenario: Class C Equipment shall be capable of generating or triggering an aural message of “Sink Rate”. + Given not implemented @AURAL_ALERT @WARNING @MOPS_278 Scenario: Class C Equipment shall be capable of generating or triggering an aural message of “Pull up”. + Given not implemented @AURAL_ALERT @WARNING @MOPS_279 Scenario: Class C Equipment shall repeat the aural message periodically for the duration of the Mode 1 warning alert condition, or until silenced by the pilot or a higher priority alert. + Given not implemented @AURAL_ALERT @WARNING @MOPS_280 Scenario: Class C Equipment shall generate a tone sweep ... + Given not implemented @VISUAL_ALERT @CAUTION @MOPS_281 Scenario: Class C Equipment shall be capable of providing an output to trigger a yellow or amber indication. + Given not implemented @VISUAL_ALERT @WARNING @MOPS_282 Scenario: Class C Equipment shall be capable of providing an output to trigger a red indication. + Given not implemented diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature index 750aa09..647f3b0 100644 --- a/taws_minimal/features/pda.feature +++ b/taws_minimal/features/pda.feature @@ -69,6 +69,8 @@ Feature: Premature Descent Alerting (PDA) @AURAL_ALERT @CAUTION @MOPS_266 Scenario: Class C Equipment shall be capable of generating or triggering an aural message of at least one of “Too Low” and “Too Low Terrain”. + Given not implemented @VISUAL_ALERT @CAUTION @MOPS_267 Scenario: Class C Equipment shall be capable of providing an output to trigger a yellow or amber indication. + Given not implemented From 4e606b02903d86b079d1da72da81ee0a52d5f330 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 22 Sep 2022 20:15:46 +0200 Subject: [PATCH 43/73] fix --- taws_minimal/features/pda.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature index 647f3b0..83d0a45 100644 --- a/taws_minimal/features/pda.feature +++ b/taws_minimal/features/pda.feature @@ -6,7 +6,7 @@ Feature: Premature Descent Alerting (PDA) height above terrain/obstacles and distance to runway. Background: - Given the aircraft is in the landing flight segment + Given the aircraft is in a landing situation @ARMING_DISARMING @MOPS_263 Scenario: Class C Equipment shall arm PDA within 5 NM of an airport. From b7d070b3519e5711a7e293c6e7da2cb393bfebb5 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 22 Sep 2022 21:39:02 +0200 Subject: [PATCH 44/73] fix --- taws_minimal/features/pda.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature index 83d0a45..bf45d8b 100644 --- a/taws_minimal/features/pda.feature +++ b/taws_minimal/features/pda.feature @@ -6,7 +6,7 @@ Feature: Premature Descent Alerting (PDA) height above terrain/obstacles and distance to runway. Background: - Given the aircraft is in a landing situation + Given the aircraft is on a landing segment @ARMING_DISARMING @MOPS_263 Scenario: Class C Equipment shall arm PDA within 5 NM of an airport. From a81a6576da39879f96b142e9a3a6ee543e0a85c0 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 23 Sep 2022 13:04:43 +0200 Subject: [PATCH 45/73] revises Mode3 cucumber feature --- taws_minimal/features/mode_3.feature | 181 +++++++++++++++++++-------- 1 file changed, 131 insertions(+), 50 deletions(-) diff --git a/taws_minimal/features/mode_3.feature b/taws_minimal/features/mode_3.feature index 4af3c86..e82114e 100644 --- a/taws_minimal/features/mode_3.feature +++ b/taws_minimal/features/mode_3.feature @@ -1,58 +1,139 @@ -#noinspection CucumberUndefinedStep -Feature: Mode 3: Negative Climb Rate or Altitude Loss - The Mode 3 alert is intended to generate caution alerts when the aircraft - loses altitude during take-off or go around. The loss of altitude can either - be based on a negative altitude rate or it can be based on a measured loss of - altitude. - - @MOPS_283 - Scenario: Mode Arming/Disarming - Given take-off is selected +@DO_367 @CLASS_C @MODE_3 +Feature: Negative Climb Rate or Altitude Loss (Mode 3) + The Mode 3 alert is intended to generate caution alerts when the aircraft loses altitude + during take-off or go around. The loss of altitude can either be based on a negative altitude + rate or it can be based on a measured loss of altitude. + + @ARMING_DISARMING @MOPS_283 + Scenario: Class C Equipment shall arm Mode 3 on take-off or go around. + Given the aircraft is on a take-off segment Then Mode 3 shall be armed - @MOPS_283 - Scenario: Mode Arming/Disarming - Given go around is selected + @ARMING_DISARMING @MOPS_283 + Scenario: Class C Equipment shall arm Mode 3 on take-off or go around. + Given the aircraft is on a go-around segment Then Mode 3 shall be armed - @MOPS_284 - Scenario: Mode Arming/Disarming - Given take-off is not selected - And go around is not selected + @ARMING_DISARMING @MOPS_284 + Scenario: Class C Equipment shall disarm Mode 3 when not in take-off and not in go around. + Given the aircraft is not on a take-off segment + Then Mode 3 shall not be armed + + @ARMING_DISARMING @MOPS_284 + Scenario: Class C Equipment shall disarm Mode 3 when not in take-off and not in go around. + Given the aircraft is not on a go-around segment Then Mode 3 shall not be armed - # MOPS_285: either alerting on Mode 1 or Mode 2 is sufficient, if both are - # used again only one is sufficient - - #Rule: Method 1 - @MOPS_286 - Scenario Outline: Must Alert - Given Mode 3 is armed - And Mode 3 is not inhibited - When the rate of descent is at least feet per minute - And the height above terrain is between 100 and feet - Then a Mode 3 caution alert is emitted within 1.3 seconds - - Examples: - | rate_of_descent | height | - | 207 | 60 | - | 533 | 600 | - | 534 | 600 | - - @MOPS_287 - Scenario: Must Not Alert when not Armed - Given Mode 3 is not armed - Then a Mode 3 caution alert is not emitted at all - - @MOPS_287 - Scenario: Must Not Alert when Inhibited - Given Mode 3 is inhibited - Then a Mode 3 caution alert is not emitted at all - - @MOPS_287 - Scenario Outline: Must Not Alert - When the rate of descent is at most feet per minute - But the height above terrain is not between 10 and feet - Then a Mode 3 caution alert is not emitted at all + @ALERT_CRITERIA @MOPS_285 + Scenario: Class C Equipment shall generate a caution alert when either the Method 1 alert criteria are satisfied or the Method 2 alert criteria are satisfied ... + Given not implemented + + Rule: Based on height above terrain/runway (Method 1) + + @ALERT_CRITERIA @CAUTION @MOPS_286 + Scenario Outline: Class C Equipment shall provide a caution alert when ... + Given the aircraft is on a take-off segment + Given Mode 3 is not inhibited + When the rate of descent is at least feet per minute + When the height above terrain is between 60.0 and feet + Then Mode 3 is armed + Then a Mode 3 caution shall be emitted + + Examples: + | min_rate_descent | max_height_terrain | + | 207.0 | 60.0 | + | 533.0 | 600.0 | + + @ALERT_CRITERIA @CAUTION @MOPS_287 + Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is not armed. + Given the aircraft is not on a take-off segment + Given Mode 3 is not inhibited + When the rate of descent is at least 207.0 feet per minute + When the height above terrain is 60.0 feet + Then Mode 3 is not armed + Then a Mode 3 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_287 + Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is inhibited. + Given the aircraft is on a take-off segment + Given Mode 3 is inhibited + When the rate of descent is at least 207.0 feet per minute + When the height above terrain is 60.0 feet + Then Mode 3 is armed + Then a Mode 3 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_287 + Scenario Outline: Class C Equipment shall not provide a Mode 3 caution alert when ... within the Must Not Alert envelope ... + Given the aircraft is on a take-off segment + Given Mode 3 is not inhibited + When the rate of descent is at most feet per minute + When the height above terrain is at least feet + Then Mode 3 is armed + Then a Mode 3 caution should not be emitted + + Examples: + | max_rate_descent | min_height_terrain | + | 49.9 | 40.0 | + | 49.9 | 175.0 | + | 446.9 | 770.0 | + + Rule: Based on the combination of height above terrain/runway and altitude loss (Method 2) + + @ALERT_CRITERIA @CAUTION @MOPS_288 + Scenario Outline: Class C Equipment shall provide a caution alert when ... + Given the aircraft is on a take-off segment + Given Mode 3 is not inhibited + When the height above terrain is between 60.0 feet + Given in the next phase + When the height above terrain is at most feet + Then Mode 3 is armed + Then a Mode 3 caution shall be emitted + + Examples: + | init_max_height_terrain | next_max_height_terrain | + | 60.0 | 34.0 | + | 600.0 | 520.0 | + + @ALERT_CRITERIA @CAUTION @MOPS_289 + Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is not armed. + Given the aircraft is not on a take-off segment + Given Mode 3 is not inhibited + When the height above terrain is 60.0 feet + Given in the next phase + When the height above terrain is at 34.0 feet + Then Mode 3 is not armed + Then a Mode 3 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_289 + Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is inhibited. + Given the aircraft is on a take-off segment + Given Mode 3 is inhibited + When the height above terrain is 60.0 feet + Given in the next phase + When the height above terrain is at 34.0 feet + Then Mode 3 is armed + Then a Mode 3 caution shall not be emitted + + @ALERT_CRITERIA @CAUTION @MOPS_289 + Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... within the Must Not Alert envelope ... + Given the aircraft is on a take-off segment + Given Mode 3 is not inhibited + When the height above terrain is at least feet + Given in the next phase + When the height above terrain is at least feet + Then Mode 3 is armed + Then a Mode 3 caution shall not be emitted + + Examples: + | init_min_height_terrain | next_min_height_terrain | + | 10.0 | 7.1 | + | 60.0 | 57.1 | + | 1600.0 | 1472.1 | + @AURAL_ALERT @CAUTION @MOPS_290 + Scenario: Class C Equipment shall be capable of generating or triggering an aural message of at least one of “Don’t Sink” and “Too Low Terrain”. + Given not implemented + @VISUAL_ALERT @CAUTION @MOPS_291 + Scenario: Class C Equipment shall be capable of providing an output to trigger a yellow or amber indication. + Given not implemented From b730e909025dff62fc4b96f038cea7ba53e4d944 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 23 Sep 2022 13:23:28 +0200 Subject: [PATCH 46/73] revises FFAC cucumber feature --- taws_minimal/features/ffac.feature | 72 ++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/taws_minimal/features/ffac.feature b/taws_minimal/features/ffac.feature index e54b490..ae5f8a3 100644 --- a/taws_minimal/features/ffac.feature +++ b/taws_minimal/features/ffac.feature @@ -1,3 +1,4 @@ +@DO_367 @CLASS_C @FFAC Feature: Five Hundred Foot Altitude Callout Altitude callouts are a category of aural annunciation occurring at a descending aircraft crossover of a particular height above terrain or height @@ -9,22 +10,55 @@ other specific altitude thresholds. Examples include “four hundred”, “fift specific approach-related callouts such as “minimums” or “decision height”. Each of these additional categories of callouts is not required. - @MOPS_292 - Scenario: Five hundred foot above terrain - Given FFAC is armed - And FFAC is not inhibited - And non-precision approach is selected - And the height above terrain is at least 500 foot - Given in the next phase - When the height above terrain is at most 500 foot - Then a FFAC annunciation alert is emitted within 1.3 seconds - - @MOPS_292 - Scenario: Five hundred foot above nearest runway elevation - Given FFAC is armed - And FFAC is not inhibited - And non-precision approach is selected - And the nearest runway elevation is at least 500 foot - Given in the next phase - When the nearest runway elevation is at most 500 foot - Then a FFAC annunciation alert is emitted within 1.3 seconds + @ARMING_DISARMING + Scenario: Class C Equipment should disarm altitude callouts when in take-off ... + Given the aircraft is on a take-off segment + Then FFAC shall not be armed + + @ARMING_DISARMING + Scenario: Class C Equipment should disarm altitude callouts when ... in a go around. + Given the aircraft is on a go-around segment + Then FFAC shall not be armed + + @ARMING_DISARMING + Scenario: Class C Equipment should arm altitude callouts when not in take-off ... + Given the aircraft is not on a take-off segment + Then FFAC shall be armed + + @ARMING_DISARMING + Scenario: Class C Equipment should arm altitude callouts when not in ... go around. + Given the aircraft is not on a go-around segment + Then FFAC shall be armed + + @ARMING_DISARMING + Scenario: Altitude callouts should be rearmed during the subsequent approach. + Given the aircraft is on an approach segment + Then FFAC shall be armed + + @AURAL_ALERT @ANNUNCIATION @MOPS_293 + Scenario: Class C Equipment shall (TAWS_MOPS_293) be capable of providing or triggering a voice callout of “five hundred” ... + Given not implemented + + Rule: Five Hundred Foot Altitude Callout above terrain + + @CALLOUT_CRITERIA @ANNUNCIATION @MOPS_292 + Scenario: Class C Equipment shall be capable of generating ... altitude callouts when ... + Given the aircraft is on an approach segment + Given non-precision approach is selected + Given FFAC is not inhibited + Given the height above terrain is at least 500 feet + Given in the next phase + When the height above terrain is at most 500 feet + Then a FFAC annunciation is emitted within 1.3 seconds + + Rule: Five Hundred Foot Altitude Callout above runway + + @CALLOUT_CRITERIA @ANNUNCIATION @MOPS_292 + Scenario: Class C Equipment shall be capable of generating ... altitude callouts when ... + Given the aircraft is on an approach segment + Given non-precision approach is selected + Given FFAC is not inhibited + Given the height above runway is at least 500 feet + Given in the next phase + When the height above runway is at most 500 feet + Then a FFAC annunciation is emitted within 1.3 seconds From 561d5648baf15fef9e50a2388cadd24c10928992 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 10 Oct 2022 17:36:43 +0200 Subject: [PATCH 47/73] rework opentaws implementation --- Cargo.lock | 1269 +++----------------------------- Cargo.toml | 8 +- opentaws/Cargo.toml | 12 +- opentaws/src/aircraft_state.rs | 532 +++++++++++++ opentaws/src/alerts.rs | 356 +++++---- opentaws/src/alerts/ffac.rs | 42 -- opentaws/src/alerts/flta.rs | 22 - opentaws/src/alerts/mode_1.rs | 96 --- opentaws/src/alerts/mode_2.rs | 22 - opentaws/src/alerts/mode_3.rs | 73 -- opentaws/src/alerts/mode_4.rs | 22 - opentaws/src/alerts/mode_5.rs | 22 - opentaws/src/alerts/pda.rs | 61 -- opentaws/src/envelope.rs | 479 +++++++++--- opentaws/src/lib.rs | 80 +- opentaws/src/macros.rs | 38 - opentaws/src/prelude.rs | 22 - opentaws/src/signal_test.rs | 67 -- opentaws/src/terrain_server.rs | 32 - opentaws/src/types.rs | 222 ------ 20 files changed, 1246 insertions(+), 2231 deletions(-) create mode 100644 opentaws/src/aircraft_state.rs delete mode 100644 opentaws/src/alerts/ffac.rs delete mode 100644 opentaws/src/alerts/flta.rs delete mode 100644 opentaws/src/alerts/mode_1.rs delete mode 100644 opentaws/src/alerts/mode_2.rs delete mode 100644 opentaws/src/alerts/mode_3.rs delete mode 100644 opentaws/src/alerts/mode_4.rs delete mode 100644 opentaws/src/alerts/mode_5.rs delete mode 100644 opentaws/src/alerts/pda.rs delete mode 100644 opentaws/src/macros.rs delete mode 100644 opentaws/src/prelude.rs delete mode 100644 opentaws/src/signal_test.rs delete mode 100644 opentaws/src/terrain_server.rs delete mode 100644 opentaws/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 873fd26..dc6c912 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,12 +24,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] -name = "arbitrary" -version = "1.1.3" +name = "approx" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ - "derive_arbitrary", + "num-traits", ] [[package]] @@ -38,177 +38,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596" -[[package]] -name = "async-channel" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "slab", -] - -[[package]] -name = "async-fs" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3ca4f8ff117c37c278a2f7415ce9be55560b846b5bc4412aaa5d29c1c3dae2" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-global-executor" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "num_cpus", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-net" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5373304df79b9b4395068fb080369ec7178608827306ce4d081cba51cac551df" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" -dependencies = [ - "async-io", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" - -[[package]] -name = "async-trait" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-tungstenite" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" -dependencies = [ - "async-std", - "futures-io", - "futures-util", - "log", - "pin-project-lite", - "tungstenite", -] - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - [[package]] name = "atty" version = "0.2.14" @@ -258,29 +87,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - [[package]] name = "bstr" version = "0.2.17" @@ -300,37 +106,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] -name = "bytecount" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - -[[package]] -name = "casey" -version = "0.3.3" +name = "bytemuck" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14" -dependencies = [ - "syn", -] +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "cast" @@ -363,81 +142,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags", - "textwrap 0.11.0", + "textwrap", "unicode-width", ] -[[package]] -name = "clap" -version = "3.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "clap_lex", - "indexmap", - "once_cell", - "strsim", - "termcolor", - "textwrap 0.15.0", -] - -[[package]] -name = "clap_derive" -version = "3.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" -dependencies = [ - "heck 0.4.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "console" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "terminal_size", - "unicode-width", - "winapi", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.3.2" @@ -455,7 +163,7 @@ checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", - "clap 2.34.0", + "clap", "criterion-plot", "csv", "itertools", @@ -528,16 +236,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - [[package]] name = "csv" version = "1.1.6" @@ -561,129 +259,31 @@ dependencies = [ ] [[package]] -name = "ctor" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "cucumber" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399fa7fc41ab7163fc49d5c2613b582b04bbf2d5342fcb1946fc1efd5b71193c" -dependencies = [ - "async-trait", - "atty", - "clap 3.2.17", - "console", - "cucumber-codegen", - "cucumber-expressions", - "derive_more", - "either", - "futures", - "gherkin", - "globwalk", - "inventory", - "itertools", - "linked-hash-map", - "once_cell", - "regex", - "sealed 0.4.0", -] - -[[package]] -name = "cucumber-codegen" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6f939adacd640286fb794ec392c068367991795db4c2c9112b748fb4fbf04f" -dependencies = [ - "cucumber-expressions", - "inflections", - "itertools", - "proc-macro2", - "quote", - "regex", - "syn", - "synthez", -] - -[[package]] -name = "cucumber-expressions" -version = "0.2.1" +name = "either" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40d2fdf5e1bb4ae7e6b25c97bf9b9d249a02243fc0fbd91075592b5f00a3bc1" -dependencies = [ - "derive_more", - "either", - "nom", - "nom_locate", - "regex", - "regex-syntax", -] +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" [[package]] -name = "derive_arbitrary" -version = "1.1.3" +name = "enum-map" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a577516173adb681466d517d39bd468293bc2c2a16439375ef0f35bba45f3d" +checksum = "f5a56d54c8dd9b3ad34752ed197a4eb2a6601bc010808eb097a04a58ae4c43e1" dependencies = [ - "proc-macro2", - "quote", - "syn", + "enum-map-derive", ] [[package]] -name = "derive_more" -version = "0.99.17" +name = "enum-map-derive" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "a9045e2676cd5af83c3b167d917b0a5c90a4d8e266e2683d6631b235c457fc27" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "either" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "flate2" version = "1.0.24" @@ -694,12 +294,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -710,120 +304,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" - -[[package]] -name = "futures-executor" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" - -[[package]] -name = "futures-task" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" - -[[package]] -name = "futures-util" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.7" @@ -835,97 +315,12 @@ dependencies = [ "wasi", ] -[[package]] -name = "gherkin" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ab17bb865b7c4fbca5133801229aeb127e254a47c29fd26968195fce9458ab" -dependencies = [ - "heck 0.3.3", - "peg", - "quote", - "serde", - "serde_json", - "syn", - "textwrap 0.12.1", - "thiserror", - "typed-builder", -] - -[[package]] -name = "ghost" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "globset" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" -dependencies = [ - "aho-corasick", - "bstr", - "fnv", - "log", - "regex", -] - -[[package]] -name = "globwalk" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" -dependencies = [ - "bitflags", - "ignore", - "walkdir", -] - -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "half" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -935,23 +330,6 @@ dependencies = [ "libc", ] -[[package]] -name = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa 1.0.3", -] - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - [[package]] name = "idna" version = "0.2.3" @@ -963,59 +341,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "ignore" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" -dependencies = [ - "crossbeam-utils", - "globset", - "lazy_static", - "log", - "memchr", - "regex", - "same-file", - "thread_local", - "walkdir", - "winapi-util", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "inflections" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "inventory" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84344c6e0b90a9e2b6f3f9abe5cc74402684e348df7b32adca28747e0cef091a" -dependencies = [ - "ctor", - "ghost", -] - [[package]] name = "itertools" version = "0.10.3" @@ -1065,15 +390,6 @@ dependencies = [ "rayon", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1095,12 +411,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "log" version = "0.4.17" @@ -1108,7 +418,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", - "value-bag", ] [[package]] @@ -1117,6 +426,15 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "matrixmultiply" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +dependencies = [ + "rawpointer", +] + [[package]] name = "memchr" version = "2.5.0" @@ -1132,12 +450,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.5.3" @@ -1148,24 +460,30 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.1" +name = "nalgebra" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "e9e0a04ce089f9401aac565c740ed30c46291260f27d4911fdbaa6ca65fa3044" dependencies = [ - "memchr", - "minimal-lexical", + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", ] [[package]] -name = "nom_locate" -version = "4.0.0" +name = "nalgebra-macros" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37794436ca3029a3089e0b95d42da1f0b565ad271e4d3bb4bad0c7bb70b10605" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" dependencies = [ - "bytecount", - "memchr", - "nom", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1247,9 +565,6 @@ name = "once_cell" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" -dependencies = [ - "parking_lot_core", -] [[package]] name = "oorandom" @@ -1257,78 +572,34 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opentaws" -version = "0.1.0" -dependencies = [ - "aviation_database", - "lazy_static", - "ringbuffer", - "serde", - "serde_arrays", - "uom", -] - -[[package]] -name = "ordered-float" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_str_bytes" -version = "6.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "peg" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" +[[package]] +name = "opentaws" +version = "0.1.0" dependencies = [ - "peg-macros", - "peg-runtime", + "aviation_database", + "enum-map", + "lazy_static", + "nalgebra", + "ringbuffer", + "serde", + "serde_arrays", + "uom", ] [[package]] -name = "peg-macros" -version = "0.6.3" +name = "ordered-float" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", + "num-traits", ] [[package]] -name = "peg-runtime" -version = "0.6.3" +name = "paste" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" [[package]] name = "percent-encoding" @@ -1336,18 +607,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "plotters" version = "0.3.2" @@ -1376,49 +635,12 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.43" @@ -1476,6 +698,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.5.3" @@ -1500,15 +728,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.6.0" @@ -1574,6 +793,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +[[package]] +name = "safe_arch" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -1599,30 +827,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "sealed" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636b9882a0f4cc2039488df89a10eb4b7976d4b6c1917fc0518f3f0f5e2c72ca" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sealed" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5e421024b5e5edfbaa8e60ecf90bda9dbffc602dbb230e6028763f85f0c68c" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "serde" version = "1.0.143" @@ -1674,76 +878,16 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signal-hook" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" - -[[package]] -name = "smol" -version = "1.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cf3b5351f3e783c1d79ab5fc604eeed8b8ae9abd36b166e8b87a089efd85e4" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "socket2" -version = "0.4.4" +name = "simba" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "c48e45e5961033db030b56ad67aef22e9c908c493a6e8348c0a0f6b93433cd77" dependencies = [ - "libc", - "winapi", + "approx", + "num-complex", + "num-traits", + "paste", + "wide", ] [[package]] @@ -1752,12 +896,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "syn" version = "1.0.99" @@ -1769,81 +907,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synthez" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033178d0acccffc5490021657006e6a8dd586ee9dc6f7c24e7608b125e568cb1" -dependencies = [ - "syn", - "synthez-codegen", - "synthez-core", -] - -[[package]] -name = "synthez-codegen" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69263462a40e46960f070618e20094ce69e783a41f86e54bc75545136afd597a" -dependencies = [ - "syn", - "synthez-core", -] - -[[package]] -name = "synthez-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8b5a4089fe1723279f06302afda64a5dacaa11a82bcbb4d08759590d4389d9" -dependencies = [ - "proc-macro2", - "quote", - "sealed 0.3.0", - "syn", -] - -[[package]] -name = "taws_minimal" -version = "0.1.0" -dependencies = [ - "arbitrary", - "async-trait", - "async-tungstenite", - "aviation_database", - "casey", - "cucumber", - "futures", - "lazy_static", - "opentaws", - "rand", - "rand_pcg", - "rayon", - "regex", - "serde", - "serde_json", - "smol", - "uom", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "textwrap" version = "0.11.0" @@ -1853,50 +916,26 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "textwrap" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -1922,36 +961,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tungstenite" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" -dependencies = [ - "base64", - "byteorder", - "bytes", - "http", - "httparse", - "log", - "rand", - "sha-1", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "typed-builder" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f85f4270f4f449a3f2c0cf2aecc8415e388a597aeacc7d55fc749c5c968c8533" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "typenum" version = "1.15.0" @@ -1989,12 +998,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-width" version = "0.1.9" @@ -2046,34 +1049,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "value-bag" -version = "1.0.0-alpha.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "walkdir" version = "2.3.2" @@ -2116,18 +1091,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.82" @@ -2187,12 +1150,13 @@ dependencies = [ ] [[package]] -name = "wepoll-ffi" -version = "0.1.2" +name = "wide" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +checksum = "b3aba2d1dac31ac7cae82847ac5b8be822aee8f99a4e100f279605016b185c5f" dependencies = [ - "cc", + "bytemuck", + "safe_arch", ] [[package]] @@ -2225,46 +1189,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Cargo.toml b/Cargo.toml index af319cb..2af263d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] members = [ "opentaws", - "taws_minimal", - "aviation_database", - "kd_tree", - "kd_tree_sort" + #"taws_minimal", + #"aviation_database", + #"kd_tree", + #"kd_tree_sort", ] diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index bd0bfa2..7e85f9b 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -5,8 +5,8 @@ authors = [ "Wanja Zaeske ", "Janick Beck ", "Umut Durak ", - ] -edition = "2018" +] +edition = "2021" license = "MIT OR Apache-2.0" description = "An open source TAWS" documentation = "https://aeronautical-informatics.github.io/openTAWS/" @@ -26,10 +26,12 @@ default = ["use-serde"] use-serde = ["uom/use_serde"] [dependencies] -aviation_database = { path = "../aviation_database"} -lazy_static = { version = "1", features = [ "spin_no_std" ] } +aviation_database = { path = "../aviation_database" } +lazy_static = { version = "1", features = ["spin_no_std"] } +enum-map = "2.4.1" +nalgebra = { version = "0.31.1", features = ["libm"] } uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } ringbuffer = "0.8" -serde = { version = "1.0", default-features = false, features = [ "derive" ] } +serde = { version = "1.0", default-features = false, features = ["derive"] } serde_arrays = "*" # Serde const generic "workaround" diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs new file mode 100644 index 0000000..0f218ee --- /dev/null +++ b/opentaws/src/aircraft_state.rs @@ -0,0 +1,532 @@ +use core::{ + fmt::Display, + marker::PhantomData, + ops::{Add, Rem}, +}; + +use lazy_static::lazy_static; +use uom::{ + fmt::DisplayStyle, + si::{ + angle::{degree, revolution}, + f64::*, + length::foot, + ratio::ratio, + time::second, + velocity::{foot_per_minute, knot}, + }, +}; + +// ToDo: turn into consts when uom supports const new +lazy_static! { + static ref ZERO_REVOLUTION: Angle = Angle::new::(0.0); + static ref QUARTER_REVOLUTION: Angle = Angle::new::(0.25); + static ref HALF_REVOLUTION: Angle = Angle::new::(0.5); + static ref ONE_REVOLUTION: Angle = Angle::new::(1.0); + static ref ZERO_LENGTH: Length = Length::new::(0.0); +} + +/// Marker for normalized AircraftStates +pub struct Normalized; + +/// Represents a normalized AircraftState. +/// A normalized AircraftState satisfies various constraints: +/// * Latitude is in [[-90 .. 90]] deg +/// * Longitude is in [[-180 ... 180]] deg +/// * Altitude above ground >= 0 foot +/// * heading is in [0 .. 360) deg +/// * track is in [0 .. 360) deg +pub type NormalizedAircraftState = AircraftState; + +/// Represents the current state of an aircraft +#[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AircraftState { + /// Time when this aircraft state was emitted + timestamp: Time, + + /// Geographic Latitude, specifying the north-south position, WGS84 + position_lat: Angle, + + /// Geographic Longitude, specifying the east-west position, WGS84 + position_lon: Angle, + + /// Height above sea level in foot + altitude: Length, + + /// Height above current terrain in foot + altitude_ground: Length, + + /// Aircraft speed as measured by GPS + speed_ground: Velocity, + + /// Airspeed as measured by pressure sensors + speed_air: Velocity, + + /// Rate of descent + climb_rate: Velocity, + + /// Angle in degrees (clockwise) between true north and the direction where the + /// aircrafts nose is pointing + heading: Angle, + + /// Angle in degrees (clockwise) between true north and the direction of movement + track: Angle, + + /// ToDo: Use Quaternions instead of Euler angles + /// The angle on the pitch axis. + /// The pitch axis has its origin at the center of gravity and is directed to the right, parallel to a line drawn from wingtip to wingtip. + /// A positive angle points the nose up above the horizon and lowers the tail. (clockwise in direction of the axis) + /// https://en.wikipedia.org/wiki/Aircraft_principal_axes#Transverse_axis_(pitch) + /// pitch: Angle, + + /// The angle on the roll axis. + /// The roll axis has its origin at the center of gravity and is directed forward, parallel to the fuselage reference line. + /// A positive angle raises the left wing and lowers the right wing. (clockwise in direction of the axis) + /// https://en.wikipedia.org/wiki/Aircraft_principal_axes#Longitudinal_axis_(roll) + /// roll: Angle, + + /// The angle on the yaw axis. + /// The yaw axis has its origin at the center of gravity and is directed towards the bottom of the aircraft, perpendicular to the wings and to the fuselage reference line. + /// A positive angle points the nose to the right. (clockwise in direction of the axis) + /// https://en.wikipedia.org/wiki/Aircraft_principal_axes#Vertical_axis_(yaw) + /// yaw: Angle, + + /// The current situation (flight segment) of the aircraft (take-off, cruise, landing, ...) + situation: Option, + + _phantom: PhantomData, +} + +impl AircraftState { + pub fn new() -> Self { + AircraftState::default() + } + + // Setterss + pub fn timestamp_mut(&mut self) -> &mut Time { + &mut self.timestamp + } + + pub fn position_latitude_mut(&mut self) -> &mut Angle { + &mut self.position_lat + } + + pub fn position_longitude_mut(&mut self) -> &mut Angle { + &mut self.position_lon + } + + pub fn altitude_mut(&mut self) -> &mut Length { + &mut self.altitude + } + + pub fn altitude_ground_mut(&mut self) -> &mut Length { + &mut self.altitude_ground + } + + pub fn speed_ground_mut(&mut self) -> &mut Velocity { + &mut self.speed_ground + } + + pub fn speed_air_mut(&mut self) -> &mut Velocity { + &mut self.speed_air + } + + pub fn climb_rate_mut(&mut self) -> &mut Velocity { + &mut self.climb_rate + } + + pub fn heading_mut(&mut self) -> &mut Angle { + &mut self.heading + } + + pub fn track_mut(&mut self) -> &mut Angle { + &mut self.track + } + + /* pub fn pitch_mut(&mut self) -> &mut Angle { + &mut self.pitch + } + + pub fn roll_mut(&mut self) -> &mut Angle { + &mut self.roll + } + + pub fn yaw_mut(&mut self) -> &mut Angle { + &mut self.yaw + } */ + + pub fn situation_mut(&mut self) -> &mut Option { + &mut self.situation + } +} + +impl AircraftState { + // Getters + pub fn timestamp(&self) -> Time { + self.timestamp + } + + pub fn position_latitude(&self) -> Angle { + self.position_lat + } + + pub fn position_longitude(&self) -> Angle { + self.position_lon + } + + pub fn altitude(&self) -> Length { + self.altitude + } + + pub fn altitude_ground(&self) -> Length { + self.altitude_ground + } + + pub fn speed_ground(&self) -> Velocity { + self.speed_ground + } + + pub fn speed_air(&self) -> Velocity { + self.speed_air + } + + pub fn climb_rate(&self) -> Velocity { + self.climb_rate + } + + pub fn heading(&self) -> Angle { + self.heading + } + + pub fn track(&self) -> Angle { + self.track + } + + /* pub fn pitch(&self) -> Angle { + self.pitch + } + + pub fn roll(&self) -> Angle { + self.roll + } + + pub fn yaw(&self) -> Angle { + self.yaw + } */ + + pub fn situation(&self) -> Option<&FlightSegment> { + self.situation.as_ref() + } + + /// Normalizes the [AircraftState] into a [NormalizedAircraftState] + pub(crate) fn normalize(&self) -> NormalizedAircraftState { + let (lat, lon) = Self::wrap_position(self.position_lat, self.position_lon); + + NormalizedAircraftState { + timestamp: self.timestamp, + + position_lat: lat, + position_lon: lon, + + altitude: self.altitude, + altitude_ground: Self::clamp_altitude_ground(self.altitude_ground), + + speed_ground: self.speed_ground, + speed_air: self.speed_air, + + climb_rate: self.climb_rate, + + heading: Self::wrap_compass_direction(self.heading), + track: Self::wrap_compass_direction(self.track), + + // pitch: Angle::new::(0.0), + // roll: Angle::new::(0.0), + // yaw: Angle::new::(0.0), + situation: self.situation.clone(), + + _phantom: PhantomData, + } + } + + fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { + let quadrant = ((lat.abs() / *QUARTER_REVOLUTION).get::().floor() as i64) % 4; + + let pole = if lat > *ZERO_REVOLUTION { + *QUARTER_REVOLUTION + } else { + -(*QUARTER_REVOLUTION) + }; + + let offset = lat % *QUARTER_REVOLUTION; + + let (lat, lon) = match quadrant { + 0 => (offset, lon), + 1 => (pole - offset, lon + *HALF_REVOLUTION), + 2 => (-offset, lon + *HALF_REVOLUTION), + 3 => (-pole + offset, lon), + _ => panic!("cannot happen"), + }; + + let lon = Self::modulo(lon + *HALF_REVOLUTION, *ONE_REVOLUTION) - *HALF_REVOLUTION; + (lat, lon) + } + + fn clamp_altitude_ground(alt_gnd: Length) -> Length { + Length::max(*ZERO_LENGTH, alt_gnd) + } + + fn wrap_compass_direction(dir: Angle) -> Angle { + Self::modulo(dir, *ONE_REVOLUTION) + } + + fn modulo + Rem>(a: U, b: U) -> U { + ((a % b) + b) % b + } +} + +impl From for AircraftState { + fn from(state: NormalizedAircraftState) -> Self { + AircraftState { + timestamp: state.timestamp, + position_lat: state.position_lat, + position_lon: state.position_lon, + altitude: state.altitude, + altitude_ground: state.altitude_ground, + speed_ground: state.speed_ground, + speed_air: state.speed_air, + climb_rate: state.climb_rate, + heading: state.heading, + track: state.track, + // pitch: state.pitch, + // roll: state.roll, + // yaw: state.yaw, + situation: state.situation.clone(), + _phantom: PhantomData, + } + } +} + +impl Display for AircraftState { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let s = Time::format_args(second, DisplayStyle::Abbreviation); + let ft = Length::format_args(foot, DisplayStyle::Abbreviation); + let deg = Angle::format_args(degree, DisplayStyle::Abbreviation); + let fpm = Velocity::format_args(foot_per_minute, DisplayStyle::Abbreviation); + let kt = Velocity::format_args(knot, DisplayStyle::Abbreviation); + + write!( + f, + " +AircrafState: {{ + timestamp: {timestamp:.4}, + altitude_sea: {altitude_sea:.2}, + altitude_ground: {altitude_ground:.2}, + climb_rate: {climb_rate:.2}, + position_lat: {position_lat:.7}, + position_lon: {position_lon:.7}, + heading: {heading:.2}, + speed: {speed:.2}, + situation: {situation} +}}", + timestamp = s.with(self.timestamp), + altitude_sea = ft.with(self.altitude), + altitude_ground = ft.with(self.altitude_ground), + climb_rate = fpm.with(self.climb_rate), + position_lat = deg.with(self.position_lat), + position_lon = deg.with(self.position_lon), + heading = deg.with(self.heading), + speed = kt.with(self.speed_ground), + situation = format_args!("{:?}", self.situation) + ) + } +} + +/// Represents a flight segment +#[derive(Clone, Debug)] +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] +pub enum FlightSegment { + /// The aircraft is in cruise flight situation + Cruise, + + /// The aircraft is in a take-off situation + TakeOff, + + // ToDo: Climb and Approach necessary? + // Climb ???, + // Approach ???, + /// The aircraft is in a landing situation + Landing { + /// Determines whether a circling approach is flown + circling_approach: bool, // Must be part of Approach + + /// Determines whether a precision approach (ILS) is flown + precision_approach: bool, // Must be part of Approach and Landing + + /// Determines wheather a steep approach is flown + steep_approach: bool, // Must be part of Approach and Landing + }, + + /// The aircraft is in a go around situation + GoAround, +} + +impl Display for FlightSegment { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + FlightSegment::TakeOff => write!(f, "Take-Off {{ }}"), + FlightSegment::Cruise => write!(f, "Cruise {{ }}"), + FlightSegment::Landing { circling_approach, precision_approach, steep_approach } => + write!(f, "Landing {{ circling: {circling_approach}, precision: {precision_approach}, steep: {steep_approach} }}"), + FlightSegment::GoAround => write!(f, "Go Around {{ }}") + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + const EPS: f64 = 1e-10; + + macro_rules! wrap_position_tests { + ($($name:ident: $pos:expr => $expected:expr),*) => {$( + #[test] + fn $name() { + let mut state = AircraftState::new(); + *state.position_latitude_mut() = Angle::new::($pos.0); + *state.position_longitude_mut() = Angle::new::($pos.1); + + let norm_state = state.normalize(); + + assert!(angle_approx_eq(norm_state.position_latitude(), Angle::new::($expected.0))); + assert!(angle_approx_eq(norm_state.position_longitude(), Angle::new::($expected.1))); + })* + }; + } + + wrap_position_tests! { + test_wrap_zero_pos: (0.0, 0.0) => (0.0, 0.0), + + test_wrap_lat_1: (10.0, 0.0) => (10.0, 0.0), + test_wrap_lat_2: (90.0, 0.0) => (90.0, -180.0), + test_wrap_lat_3: (100.0, 0.0) => (80.0, -180.0), + test_wrap_lat_4: (180.0, 0.0) => (0.0, -180.0), + test_wrap_lat_5: (190.0, 0.0) => (-10.0, -180.0), + test_wrap_lat_6: (270.0, 0.0) => (-90.0, 0.0), + test_wrap_lat_7: (280.0, 0.0) => (-80.0, 0.0), + test_wrap_lat_8: (360.0, 0.0) => (0.0, 0.0), + test_wrap_lat_9: (370.0, 0.0) => (10.0, 0.0), + test_wrap_lat_10: (450.0, 0.0) => (90.0, -180.0), + + test_wrap_lon_1: (0.0, 10.0) => (0.0, 10.0), + test_wrap_lon_2: (0.0, 180.0) => (0.0, -180.0), + test_wrap_lon_3: (0.0, 190.0) => (0.0, -170.0), + test_wrap_lon_4: (0.0, 350.0) => (0.0, -10.0), + test_wrap_lon_5: (0.0, 360.0) => (0.0, 0.0), + test_wrap_lon_6: (0.0, 370.0) => (0.0, 10.0), + test_wrap_lon_7: (0.0, 540.0) => (0.0, -180.0), + + test_wrap_lat_lon_1: (45.0, 45.0) => (45.0, 45.0), + test_wrap_lat_lon_2: (90.0, 90.0) => (90.0, -90.0), + test_wrap_lat_lon_3: (135.0, 135.0) => (45.0, -45.0), + test_wrap_lat_lon_4: (180.0, 180.0) => (0.0, 0.0), + test_wrap_lat_lon_5: (225.0, 225.0) => (-45.0, 45.0), + test_wrap_lat_lon_6: (270.0, 270.0) => (-90.0, -90.0), + test_wrap_lat_lon_7: (360.0, 360.0) => (0.0, 0.0), + test_wrap_lat_lon_8: (405.0, 405.0) => (45.0, 45.0), + test_wrap_lat_lon_9: (450.0, 450.0) => (90.0, -90.0) + } + + #[test] + fn test_clamp_pos_alt_gnd() { + let mut state = AircraftState::new(); + *state.altitude_ground_mut() = Length::new::(1000.0); + + let norm_state = state.normalize(); + + assert!(length_approx_eq( + norm_state.altitude_ground(), + Length::new::(1000.0) + )) + } + + #[test] + fn test_clamp_neg_alt_gnd() { + let mut state = AircraftState::new(); + *state.altitude_ground_mut() = Length::new::(-1000.0); + + let norm_state = state.normalize(); + + assert!(length_approx_eq( + norm_state.altitude_ground(), + Length::new::(0.0) + )) + } + + macro_rules! wrap_heading_tests { + ($($name:ident: $hdg:expr => $expected:expr),*) => {$( + #[test] + fn $name() { + let mut state = AircraftState::new(); + *state.heading_mut() = Angle::new::($hdg); + + let norm_state = state.normalize(); + + assert!(angle_approx_eq(norm_state.heading(), Angle::new::($expected))); + })* + }; + } + + wrap_heading_tests! { + test_wrap_heading_1: 0.0 => 0.0, + test_wrap_heading_2: 10.0 => 10.0, + test_wrap_heading_3: 90.0 => 90.0, + test_wrap_heading_4: 180.0 => 180.0, + test_wrap_heading_5: 270.0 => 270.0, + test_wrap_heading_6: 360.0 => 0.0, + + test_wrap_heading_7: -10.0 => 350.0, + test_wrap_heading_8: -90.0 => 270.0, + test_wrap_heading_9: -180.0 => 180.0, + test_wrap_heading_10: -270.0 => 90.0, + test_wrap_heading_11: -360.0 => 0.0 + } + + macro_rules! wrap_track_tests { + ($($name:ident: $trk:expr => $expected:expr),*) => {$( + #[test] + fn $name() { + let mut state = AircraftState::new(); + *state.track_mut() = Angle::new::($trk); + + let norm_state = state.normalize(); + + assert!(angle_approx_eq(norm_state.track(), Angle::new::($expected))); + })* + }; + } + + wrap_track_tests! { + test_wrap_track_1: 0.0 => 0.0, + test_wrap_track_2: 10.0 => 10.0, + test_wrap_track_3: 90.0 => 90.0, + test_wrap_track_4: 180.0 => 180.0, + test_wrap_track_5: 270.0 => 270.0, + test_wrap_track_6: 360.0 => 0.0, + + test_wrap_track_7: -10.0 => 350.0, + test_wrap_track_8: -90.0 => 270.0, + test_wrap_track_9: -180.0 => 180.0, + test_wrap_track_10: -270.0 => 90.0, + test_wrap_track_11: -360.0 => 0.0 + } + + fn angle_approx_eq(value: Angle, target: Angle) -> bool { + (target - value).abs() < Angle::new::(EPS) + } + + fn length_approx_eq(value: Length, target: Length) -> bool { + (target - value).abs() < Length::new::(EPS) + } +} diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 5051060..b4d88df 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,33 +1,9 @@ -use core::fmt; +use crate::{TawsAlert, TawsAlerts}; +use enum_map::{Enum, EnumMap}; -use crate::types::{AircraftState, TawsConfig}; - -mod ffac; -mod flta; -mod mode_1; -mod mode_2; -mod mode_3; -mod mode_4; -mod mode_5; -mod pda; - -pub mod functionalities { - use super::*; - - pub use ffac::*; - pub use flta::*; - pub use mode_1::*; - pub use mode_2::*; - pub use mode_3::*; - pub use mode_4::*; - pub use mode_5::*; - pub use pda::*; -} - -/// Available alerts from the TAWS. -#[derive(Clone, Copy, Debug, PartialEq, Hash)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] -pub enum Alert { +/// Alert Source (TAWS functionallities) +#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)] +pub enum AlertSource { /// Forward Lookig Terrain Avoidance Flta, @@ -53,224 +29,224 @@ pub enum Alert { Mode5, // TODO add more } -impl Eq for Alert {} -/// Importance level of an alert -/// -/// Orderd by high priority to low priority (top to bottom) -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Hash)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] +/// TAWS Alert levels +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlertLevel { /// The level or category of alert for conditions that require immediate flight crew awareness /// and immediate flight crew response. Warning, /// The level or category of alert for conditions that require immediate flight crew awareness - /// and a less urgent subsequent flight crew response than a warning alert. + /// and a less urgent subsequent flight crew response than a warning alert. Caution, /// The level or category of an annunciation which does not represent a threat but still /// requires awareness by the crew Annunciation, } -impl Eq for AlertLevel {} - -/// Get the priority of a n (Alert, AlertLevel) tupel -/// -/// A low value means a high priority. -/// TODO move to every alert file -pub fn priority(alert: Alert, alert_level: AlertLevel) -> u8 { - use Alert::*; - use AlertLevel::*; - - match (alert, alert_level) { - (Mode1, Warning) => 2, - (Mode2, Warning) => 3, - (Flta, Warning) => 6, - (Mode2, Caution) => 9, - (Flta, Caution) => 11, - (Mode4, Caution) => 13, // Terrain caution - (Pda, Caution) => 14, - //(Mode4, Caution)=>16 // Gear caution - //(Mode4, Caution)=>17 // Flaps caution - (Mode1, Caution) => 18, - (Mode3, Caution) => 19, - (Mode5, Caution) => 20, - _ => u8::MAX, // TODO is this a safe assumption - } -} -/// Collection of a all alerts which are currently present in the TAWS -#[derive(Debug, PartialEq)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AlertState { - /// Alerts which are not to be disclosed to the crew to avoid nuisance, but still where triggered - // Workaround until generic arrays are allowed in serde - // https://github.com/serde-rs/serde/issues/1937 - #[serde(with = "serde_arrays")] - all_alerts: [Option<(Alert, AlertLevel)>; N], -} +/// Represents a TAWS alert +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct Alert { + /// The source resp. the TAWS functionallity which emitted this alert + pub source: AlertSource, -impl AlertState { - pub fn alerts_total_count(&self) -> usize { - self.all_alerts.iter().filter(|e| e.is_some()).count() - } + /// The alert level of this alert + pub level: AlertLevel, +} - pub fn priority_alert(&self) -> Option<(Alert, AlertLevel)> { - self.all_alerts - .iter() - .filter_map(|o| { - o.map(|(alert, alert_level)| (priority(alert, alert_level), (alert, alert_level))) - }) - .min_by_key(|(p, _)| *p) - .map(|(_, alert_stuff)| alert_stuff) +impl TawsAlert for Alert { + fn source(&self) -> AlertSource { + self.source } - /// Get an iterator to the alerts - pub fn iter(&self) -> impl Iterator { - self.into_iter() + fn level(&self) -> AlertLevel { + self.level } +} - /// updates internal alerts with new alerts, removing all old alerts. Prioritizes as well. - pub fn insert(&mut self, new_alert: Alert, new_alert_level: AlertLevel) { - let mut already_present = false; - - for (existing_alert, ref mut existing_alert_level) in - self.all_alerts.iter_mut().filter_map(|e| *e) - { - // check if alert is already present - if existing_alert == new_alert { - // promote alerts of lower priority to higher priority - if new_alert_level < *existing_alert_level { - *existing_alert_level = new_alert_level; - } - already_present = true; - } +impl From<(AlertSource, AlertLevel)> for Alert { + fn from(alert: (AlertSource, AlertLevel)) -> Self { + Alert { + source: alert.0, + level: alert.1, } + } +} - // lets find a free spot - if !already_present { - if let Some(option) = self.all_alerts.iter_mut().find(|e| e.is_none()) { - *option = Some((new_alert, new_alert_level)); - } - } +impl From for (AlertSource, AlertLevel) { + fn from(alert: Alert) -> Self { + (alert.source, alert.level) } } -impl Default for AlertState { - fn default() -> Self { - Self { - all_alerts: [None; N], +/// Represents a set of [Alerts](Alert) +#[derive(Default, Debug)] +pub struct Alerts { + alerts: EnumMap>, +} + +impl Alerts { + /// Inserts the specified alert into the set. + /// Already existing alerts are replaced if the [new_alert] has a higher alert level. + /// # Arguments + /// * `new_alert` - the new alert which is added to the set of alerts + /// + /// # Examples + /// ``` + /// + /// use opentaws::{*, alerts::*}; + /// let mut alerts = Alerts::default(); + /// alerts.insert((AlertSource::Mode1, AlertLevel::Caution).into()); + /// assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Annunciation)); + /// assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Caution)); + /// + /// ``` + pub fn insert(&mut self, new_alert: Alert) { + let current_alert = &self.alerts[new_alert.source]; + + if current_alert + .as_ref() + .map_or(true, |alert| new_alert.level < alert.level) + { + self.alerts[new_alert.source].replace(new_alert); } } } -/// An iterator over an `AlertState` -pub struct AlertStateIter { - sorted_alerts: [Option<(Alert, AlertLevel)>; N], - index: usize, -} +impl TawsAlerts for Alerts { + type Alert = Alert; -impl Iterator for AlertStateIter { - type Item = (Alert, AlertLevel); + fn is_alert_active(&self, alert_src: AlertSource, min_level: AlertLevel) -> bool { + let current_alert = &self.alerts[alert_src]; - fn next(&mut self) -> Option { - let maybe_item = self.sorted_alerts.get(self.index).cloned().flatten(); - self.index += 1; - maybe_item + match current_alert { + Some(alert) => alert.level <= min_level, + None => false, + } } } -impl IntoIterator for &AlertState { - type Item = (Alert, AlertLevel); - type IntoIter = AlertStateIter; +impl<'a> IntoIterator for &'a Alerts { + type Item = &'a Alert; + type IntoIter = AlertsIter<'a>; + fn into_iter(self) -> Self::IntoIter { - let mut alerts = self.all_alerts; - //TODO where do we do prioritisation - //alerts.sort_by_key(|option| option.map(|(a, l)| priority(a, l)).unwrap_or(u8::MAX)); - // does not work on no_std. - // TODO implement a small sorting algorithm - - AlertStateIter { - sorted_alerts: alerts, + AlertsIter { + alerts: self.alerts.as_slice(), index: 0, } } } -/// Trait which is to be fulfilled by all functionalities -pub trait AlertSystem<'a>: fmt::Debug + Send { - /// Allows this system to be instantiated - fn new(config: &'a TawsConfig<'a>) -> Self - where - Self: Sized; - - /// Returns whether this alarm is armed. - /// - /// Arming refers to the automatic switching on of a function by - /// the Equipment (DO-367 Chapter 1.9). - fn is_armed(&self) -> bool; - - /// Arm this alert - fn arm(&mut self); +/// Represents an iterator over all possible [Alerts](Alert) from all [AlertSources](AlertSource). +pub struct AlertsIter<'a> { + alerts: &'a [Option], + index: usize, +} - /// Disarm this alert - fn disarm(&mut self); +impl<'a> Iterator for AlertsIter<'a> { + type Item = &'a Alert; - /// Dismiss this alert - fn inhibit(&mut self); + fn next(&mut self) -> Option { + loop { + if self.index >= self.alerts.len() { + return None; + } - /// Enable this alert - fn uninhibit(&mut self); + let alert = &self.alerts[self.index]; + self.index += 1; - /// Returns whether this alarm is inhibited - fn is_inhibited(&self) -> bool; + if alert.is_none() { + continue; + } - /// Process a new AircraftState, emit alerts if appropiate - /// - /// The `u8` refers to the Priority of this AlertFunctionality - fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)>; + return alert.as_ref(); + } + } } -#[cfg(test)] -mod test { +mod tests { + #![allow(unused_imports)] //ToDo: just to satisfy clippy use super::*; - /// This is the maximum number of different alerts in an alert_state - const ALERT_STATE_SIZE: usize = 8; + #[test] + fn alert_source_equality() { + let a = AlertSource::Mode1; + let b = AlertSource::Mode1; + let c = AlertSource::Mode2; + + assert!(a == b); + assert!(a != c); + } #[test] - pub fn alert_state_propagates_alerts() { - let mut alert_state = AlertState::::default(); - let test_alerts = [(Alert::Mode3, AlertLevel::Caution)]; - for (new_alert, new_alert_level) in &test_alerts { - alert_state.insert(*new_alert, *new_alert_level); - } + fn alert_level_ord() { + assert!(AlertLevel::Warning < AlertLevel::Caution); + assert!(AlertLevel::Caution < AlertLevel::Annunciation); + } - assert_eq!(test_alerts.len(), alert_state.alerts_total_count()) + #[test] + fn alert_from_tuple() { + let alert: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); + assert!(alert.source == AlertSource::Mode1); + assert!(alert.level == AlertLevel::Warning); } #[test] - pub fn alert_state_usage() { - let alts = AlertState::::default(); + fn alert_to_tuple() { + let alert_tuple = (AlertSource::Mode1, AlertLevel::Warning); + let alert: Alert = alert_tuple.into(); + assert!(>::into(alert) == alert_tuple); + } - // using match - for x in &alts { - match x { - (Alert::Mode1, AlertLevel::Caution) if 1 > 0 => {} + #[test] + fn alert_source() { + let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); + assert!(a.source() == AlertSource::Mode1); + } - (Alert::Mode1, AlertLevel::Caution) => {} - (Alert::Mode1, AlertLevel::Warning) => {} - _ => {} - } - } + #[test] + fn alert_level() { + let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); + assert!(a.level() == AlertLevel::Warning); + } - // using match lazily - for x in &alts { - match x { - (_, AlertLevel::Caution) if 1 > 0 => {} - _ => {} - } - } + #[test] + fn alert_eq() { + let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); + let b: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); + let c: Alert = (AlertSource::Mode3, AlertLevel::Warning).into(); + let d: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); + + assert!(a == b); + assert!(a != c); + assert!(a != d); + assert!(c != d); + } + + #[test] + fn alerts_default() { + let alerts: Alerts = Alerts::default(); + assert!(alerts.alerts[AlertSource::Mode1] == None) + } + + #[test] + fn alerts_insert() { + let mut alerts: Alerts = Alerts::default(); + let alert: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); + alerts.insert(alert); + assert!(alerts.alerts[AlertSource::Mode1] == Some(alert)); + } + + #[test] + fn alerts_is_active() { + let mut alerts: Alerts = Alerts::default(); + let alert: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); + alerts.insert(alert); + assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Annunciation)); + assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Caution)); + assert!(!alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Warning)); } } diff --git a/opentaws/src/alerts/ffac.rs b/opentaws/src/alerts/ffac.rs deleted file mode 100644 index 9fc2687..0000000 --- a/opentaws/src/alerts/ffac.rs +++ /dev/null @@ -1,42 +0,0 @@ -use super::*; -use crate::prelude::*; - -#[derive(Debug)] -pub struct Ffac { - armed: bool, - inhibited: bool, - last_height: Length, -} - -impl<'a> AlertSystem<'a> for Ffac { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: true, - inhibited: false, - last_height: Length::new::(0.0), - } - } - - arm_inhibit!(); - - /// __Notes__: - /// + Per the text in chapter 2.2.1.1.13.2 only "one of the following altitude callouts" must - /// be generated - /// + MOPS_125 speaks of non-precision approaches. However, per Note 3 of chapter - /// 2.2.1.1.13.2, emitation of FFAC "is recommended for all approaches" - fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { - let fivehundred = Length::new::(500.0); - let mut result = None; - - // TODO Do we have to check against nearest runway? - // TODO Is it possible to disarm the FFAC? - - if self.last_height >= fivehundred && state.altitude_ground < fivehundred { - result = Some((AlertLevel::Annunciation, u8::default())); - } - - self.last_height = state.altitude_ground; - - armed_return!(self, result) - } -} diff --git a/opentaws/src/alerts/flta.rs b/opentaws/src/alerts/flta.rs deleted file mode 100644 index c5739e1..0000000 --- a/opentaws/src/alerts/flta.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Flta { - armed: bool, - inhibited: bool, -} - -impl<'a> AlertSystem<'a> for Flta { - fn new(_config: &'a TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { - armed_return!(self, None) - } -} diff --git a/opentaws/src/alerts/mode_1.rs b/opentaws/src/alerts/mode_1.rs deleted file mode 100644 index b4cffe0..0000000 --- a/opentaws/src/alerts/mode_1.rs +++ /dev/null @@ -1,96 +0,0 @@ -use uom::si::{length::foot, velocity::foot_per_minute}; - -use crate::envelope::Envelope; -use crate::types::*; - -use super::*; - -#[derive(Clone, Debug)] -pub struct Mode1 { - armed: bool, - inhibited: bool, -} - -impl Default for Mode1 { - fn default() -> Self { - Self { - armed: true, - inhibited: false, - } - } -} - -impl<'a> AlertSystem<'a> for Mode1 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: true, - inhibited: false, - } - } - - //TODO add real priority - fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { - let altitude = state.altitude_ground.get::(); - let rod = -state.climb_rate.get::(); - - let result = match state.steep_approach { - true if WARNING_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { - Some((AlertLevel::Warning, u8::default())) - } - true if CAUTION_ENVELOPE_STEEP_APPROACH.contains(rod, altitude) => { - Some((AlertLevel::Caution, u8::default())) - } - false if WARNING_ENVELOPE.contains(rod, altitude) => { - Some((AlertLevel::Warning, u8::default())) - } - false if CAUTION_ENVELOPE.contains(rod, altitude) => { - Some((AlertLevel::Caution, u8::default())) - } - - //self.caution_envelope - _ => None, - }; - - armed_return!(self, result) - } - - arm_inhibit!(); -} - -lazy_static::lazy_static! { - static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new([ - (1200.0, 11.0), - (2550.0, 1550.0), - (4800.0, 2900.0), - (10000.0, 4000.0), - (10001.0, 4000.0), - ]) - .unwrap(); - - static ref CAUTION_ENVELOPE_STEEP_APPROACH: Envelope<5> = Envelope::new([ - (1350.0, 11.0), - (2700.0, 1550.0), - (5300.0, 2900.0), - (10000.0, 4000.0), - (10001.0, 4000.0), - ]) - .unwrap(); - - static ref WARNING_ENVELOPE: Envelope<5> = Envelope::new([ - (1400.0, 11.0), - (2500.0, 1300.0), - (7500.0, 2500.0), - (11000.0, 3000.0), - (11001.0, 3000.0), - ]) - .unwrap(); - - static ref WARNING_ENVELOPE_STEEP_APPROACH: Envelope<5> = Envelope::new([ - (1550.0, 11.0), - (2650.0, 1300.0), - (8000.0, 2500.0), - (11000.0, 3000.0), - (11001.0, 3000.0), - ]) - .unwrap(); -} diff --git a/opentaws/src/alerts/mode_2.rs b/opentaws/src/alerts/mode_2.rs deleted file mode 100644 index 2c0a714..0000000 --- a/opentaws/src/alerts/mode_2.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Mode2 { - armed: bool, - inhibited: bool, -} - -impl<'a> AlertSystem<'a> for Mode2 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { - armed_return!(self, None) - } -} diff --git a/opentaws/src/alerts/mode_3.rs b/opentaws/src/alerts/mode_3.rs deleted file mode 100644 index ee390dc..0000000 --- a/opentaws/src/alerts/mode_3.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::*; -use uom::num::Zero; -use uom::si::f64::Length; - -use crate::envelope::Envelope; -use crate::prelude::*; - -#[derive(Debug)] -pub struct Mode3 { - armed: bool, - inhibited: bool, - max_altitude_ground: Length, -} - -impl<'a> AlertSystem<'a> for Mode3 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - max_altitude_ground: Length::zero(), - } - } - - arm_inhibit!(); - - fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { - let armed = state.go_around || state.take_off; - if let (false, true) = (self.armed, armed) { - self.max_altitude_ground = state.altitude_ground - } - self.armed = armed; - - let mut result = None; - if armed { - if self.max_altitude_ground < state.altitude_ground { - self.max_altitude_ground = state.altitude_ground; - } - let alt_loss = (self.max_altitude_ground - state.altitude_ground).get::(); - let altitude = state.altitude_ground.get::(); - let rod = -state.climb_rate.get::(); - - if CAUTION_ENVELOPE_METHODE_1.contains(rod, altitude) - || CAUTION_ENVELOPE_METHODE_2.contains(alt_loss, altitude) - { - result = Some((AlertLevel::Caution, u8::default())); - } - }; - - armed_return!(self, result) - } -} - -lazy_static::lazy_static! { - /// CAUTION Envelope for Methode 1 - /// X-Axis is Rate of Decent in foot per minute - /// Y-Axis is Height above Terrain in foot - static ref CAUTION_ENVELOPE_METHODE_1: Envelope<3> = Envelope::new([ - (125.0, 50.0), - (480.0, 680.0), - (481.0, 680.0), - ]) - .unwrap(); - - /// CAUTION Envelope for Methode 2 - /// X-Axis is Altitude Loss in foot - /// Y-Axis is Height above Terrain in foot - static ref CAUTION_ENVELOPE_METHODE_2: Envelope<3> = Envelope::new([ - (11.0, 35.0), - (104.0, 1100.0), - (104.0001, 1100.0), - ]) - .unwrap(); -} diff --git a/opentaws/src/alerts/mode_4.rs b/opentaws/src/alerts/mode_4.rs deleted file mode 100644 index 7f7dd1a..0000000 --- a/opentaws/src/alerts/mode_4.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Mode4 { - armed: bool, - inhibited: bool, -} - -impl<'a> AlertSystem<'a> for Mode4 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { - armed_return!(self, None) - } -} diff --git a/opentaws/src/alerts/mode_5.rs b/opentaws/src/alerts/mode_5.rs deleted file mode 100644 index a396a6e..0000000 --- a/opentaws/src/alerts/mode_5.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct Mode5 { - armed: bool, - inhibited: bool, -} - -impl<'a> AlertSystem<'a> for Mode5 { - fn new(_config: &TawsConfig) -> Self { - Self { - armed: false, - inhibited: false, - } - } - - arm_inhibit!(); - - fn process(&mut self, _state: &AircraftState) -> Option<(AlertLevel, u8)> { - armed_return!(self, None) - } -} diff --git a/opentaws/src/alerts/pda.rs b/opentaws/src/alerts/pda.rs deleted file mode 100644 index 8d64f66..0000000 --- a/opentaws/src/alerts/pda.rs +++ /dev/null @@ -1,61 +0,0 @@ -use super::*; -use crate::envelope::Envelope; -use crate::prelude::*; -use uom::si::length::nautical_mile; - -#[derive(Debug)] -pub struct Pda<'a> { - armed: bool, - inhibited: bool, - taws_config: &'a TawsConfig<'a>, -} - -impl<'a> AlertSystem<'a> for Pda<'a> { - fn new(config: &'a TawsConfig<'a>) -> Self { - Self { - armed: false, - inhibited: false, - taws_config: config, - } - } - - arm_inhibit!(); - - fn process(&mut self, state: &AircraftState) -> Option<(AlertLevel, u8)> { - let position = state.position(); - let nearest_airport = self.taws_config.terrain_server.nearest_airport(&position); - let distance = position.great_circle(&nearest_airport.pos); - let distance_nm = distance.get::(); - - // MOPS_263 requires PDA to be armed within 5NM of an airport - // But since it may be armed beyond that, we arm/disarm it with a - // distance of 8NM - self.armed = distance_nm <= 8.0; - - // In 2.2.3.1.7.2 some considerations are presented for reducing nuisance alerts - // All of them are satisfied by our CAUTION_ENVELOPE - let result = if self.armed - && CAUTION_ENVELOPE.contains(distance_nm, state.altitude_ground.get::()) - { - Some((AlertLevel::Caution, u8::default())) - } else { - None - }; - - armed_return!(self, result) - } -} - -lazy_static::lazy_static! { - /// CAUTION Envelope for PDA - /// X-Axis is Distance to Airport in nautical miles - /// Y-Axis is Height above Terrain in foot - static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new([ - (0.9, 5.0), - (0.90001, 85.0), - (1.8, 155.0), - (2.3, 175.0), - (2.4, 175.0), - ]) - .unwrap(); -} diff --git a/opentaws/src/envelope.rs b/opentaws/src/envelope.rs index c2ad0db..f21f66e 100644 --- a/opentaws/src/envelope.rs +++ b/opentaws/src/envelope.rs @@ -1,139 +1,416 @@ -/// `Envelope` helps checking whether a 2D point is inside of a 2D Envelope - that is a polygon without vertical lines. +type Vector2 = nalgebra::Vector2; + +/// Represents a TAWS Envelope which defines under what conditions an alert should and should not be emitted. pub struct Envelope { - points: [(f64, f64); N], - derivatives: [f64; N], // TODO make this N-1 + /// Defines the operating limits of this envelope.
+ /// For states outside these limits the envelope is not defined. + limits: Rect, + /// Defines the conditions under which an alert should or should not be emitted.
+ /// The start and end point must coincide with the envelope limits. + /// The other points must be inside of the envelope limits. + polygon: Polygon, } impl Envelope { - /// Creates an envelope from point pairs - /// - /// The point pairs must be orderd by x values in ascending order. There must be no two points - /// with the same x value. The lower left bound is is the first point. - /// - /// Each section between two successive x points is interpolated by a linear function. The - /// interpolation function of the last section is extendend to +∞. Use an additional point with - /// the same y value as the prior point to cause an extrapolation parallel to the x axis for - /// the slope after the last point. - // - // # Example - // - // ``` - // use opentaws::envelope::Envelope; - // // The last point ensure that the slope is extended with a function parallel to the x axis - // let points = vec![(1908, 150), (2050, 300), (10300, 1958), (10301, 1958)]; - // let envelope = Envelope::new(&points).expect("invalid points given to envelope"); - // ``` - pub fn new(points: [(T, U); N]) -> Option - where - T: Into + Copy, - U: Into + Copy, - { - if N < 2 { - // List is too small! - return None; + /// Creates a new Envelope from the given envelope limits and polygon points. + /// # Arguments + /// * `limits` - the limits of the envelope in which the envelope is defined. Must be finite. + /// * `points` - the polygon points which define the envelope. At least 3 points are nessecary. All points must be finite. + /// ToDO (maybe): Augment the polygon to the envelope limits by adding a new start point and new end points to close the polygon with the envelope limits. + pub fn try_new(limits: Rect, points: [Vector2; N]) -> Result { + if !Self::are_valid_limits(&limits) { + return Err(()); } - let points_raw = points; - let mut points: [(f64, f64); N] = [(points_raw[0].0.into(), points_raw[0].1.into()); N]; - for i in 1..N { - points[i] = (points_raw[i].0.into(), points_raw[i].1.into()); - if points[i - 1].0 >= points[i].0 { - // This means either the list is not sorted or two values are identical - return None; - } + if !Self::are_points_valid(&limits, &points) { + return Err(()); } - // TODO port this to iter code once libcore allows to collect into arrays - /* - let derivatives = (0..(N - 1)) - .map(|i| { - let (x, y) = points[i]; - let (x_, y_) = points[i + 1]; - (y_ - y) / (x_ - x) - }) - .collect(); - */ + Ok(Self { + limits, + polygon: Polygon::try_new(points)?, + }) + } + + /// checks wether the given limits are sufficent for an envelope. + fn are_valid_limits(limits: &Rect) -> bool { + limits.min.x.is_finite() + && limits.min.y.is_finite() + && limits.max.x.is_finite() + && limits.max.y.is_finite() + } - let mut derivatives = [0f64; N]; - for i in 0..(N - 1) { - let (x, y) = points[i]; - let (x_, y_) = points[i + 1]; - derivatives[i] = (y_ - y) / (x_ - x) + /// checks whether the given polygon points are sufficent for an envelope. + /// the polygon must start and end on the envelope limits. all in-between points must be within the envelope limit. + fn are_points_valid(limits: &Rect, points: &[Vector2; N]) -> bool { + if N < 3 { + return false; } - Some(Self { - points, - derivatives, - }) - } + let first_point = points.first().unwrap(); + let last_point = points.last().unwrap(); + if !limits.is_point_on_boundary(*first_point) || !limits.is_point_on_boundary(*last_point) { + return false; + } - /// Checks wether a point is in the envelope - pub fn contains(&self, x: T, y: U) -> bool - where - T: Into + Copy, - U: Into + Copy, - { - let (x, y) = (x.into(), y.into()); - let minimum = self.points[0]; - if x < minimum.0 || y < minimum.1 { + let mid_points = &points[1..N - 1]; + if !mid_points.iter().all(|point| limits.contains(*point)) { return false; } - let mut interval_index = (N - 1) - 1; // TODO make this `derivatives.len() - 1` - for (i, p) in self.points[0..self.derivatives.len() - 1] + true + } + + /// Returns whether the envelope is defined for the specified point. + /// # Arguments + /// * `point` - The point which is tested + /// # Returns + /// * `true` if the given point is within the envelope limits; otherwise `false`. + pub fn is_within_limits(&self, point: Vector2) -> bool { + self.limits.contains(point) + } + + /// Determines whether the specified state is within the envelope. + /// # Arguments + /// * `point` - The state which is tested against the envelope. + /// # Returns + /// * `Ok(bool)` - Indicates whether the given point is within the envelope. + /// * `Err()` - The given point is not within the envelope limits. + pub fn contains(&self, point: Vector2) -> Result { + if !self.is_within_limits(point) { + return Err(()); + } + + Ok(self.polygon.contains(point)) + } +} + +/// Represents an Polygon. +struct Polygon { + /// Points which define the polygon. + /// the last segement from point[-1] to point[0] is implied. + points: [Vector2; N], +} + +impl Polygon { + /// tries to create a new polygon from the given points. + /// at least 2 points are nessecary. all points must be finite. + fn try_new(points: [Vector2; N]) -> Result { + if N < 2 { + return Err(()); + } + + if !Self::are_points_valid(&points) { + return Err(()); + } + + Ok(Self { points }) + } + + /// check given points. + fn are_points_valid(points: &[Vector2; N]) -> bool { + points .iter() - .enumerate() - { - // TODO remove the -1 - let p_ = self.points[i + 1]; - if p.0 <= x && x <= p_.0 { - interval_index = i; - break; + .all(|point| point.x.is_finite() && point.y.is_finite()) + } + + /// returns the points of the polygon. + fn points(&self) -> &[Vector2; N] { + &self.points + } + + /// returns the axis-aligned bounding-box for the polygon. + fn bounding_box(&self) -> Rect { + let mut min = Vector2::new(f64::INFINITY, f64::INFINITY); + let mut max = Vector2::new(f64::NEG_INFINITY, f64::NEG_INFINITY); + + for p in self.points { + if p.x < min.x { + min.x = p.x; + } else if p.x > max.x { + max.x = p.x; + } + + if p.y < min.y { + min.y = p.y; + } else if p.y > max.y { + max.y = p.y; } } - let fx = self.points[interval_index].1 - + self.derivatives[interval_index] * (x - self.points[interval_index].0); - y <= fx + Rect::new(min, max) + } + + /// returns an iterator over + fn segments(&self) -> impl Iterator + '_ { + (0..N).map(|i| (self.points[i], self.points[(i + 1) % N]).into()) + } + + /// determines whether the specfied point is within or on the polygon boundary. + /// works for all kind of polygons: simple, non-convex and non-simple (self-intersecting). + /// https://www.engr.colostate.edu/~dga/documents/papers/point_in_polygon.pdf + fn contains(&self, point: Vector2) -> bool { + let mut winding_num = 0.0; + + for segment in self.segments() { + if segment.contains(point) { + return true; + } + + let (p1, p2) = segment.translate(-point).into(); + + if p1.y * p2.y < 0.0 { + let r = p1.x + (p1.y * (p2.x - p1.x)) / (p1.y - p2.y); + + if r > 0.0 { + if p1.y < 0.0 { + winding_num += 1.0; + } else { + winding_num -= 1.0; + } + } + } else if p1.y == 0.0 && p1.x > 0.0 { + if p2.y > 0.0 { + winding_num += 0.5; + } else { + winding_num -= 0.5; + } + } else if p2.y == 0.0 && p2.x > 0.0 { + if p1.y < 0.0 { + winding_num += 0.5; + } else { + winding_num -= 0.5; + } + } + } + + winding_num != 0.0 } } -#[cfg(test)] -mod test { - use super::*; +/// Represents an axis-aligned rectangle. +#[derive(Copy, Clone, Default, Debug, PartialEq)] +pub struct Rect { + /// lower left corner + min: Vector2, + /// upper right corner + max: Vector2, +} - fn init_envelope() -> Envelope<4> { - let points = [(1600, 100), (1850, 300), (10100, 1958), (10101, 1958)]; - Envelope::new(points).unwrap() +impl Rect { + /// Creates a rectanlge from two points. + fn new(p1: Vector2, p2: Vector2) -> Rect { + let min = Vector2::new(f64::min(p1.x, p2.x), f64::min(p1.y, p2.y)); + let max = Vector2::new(f64::max(p1.x, p2.x), f64::max(p1.y, p2.y)); + + Rect { min, max } } - #[test] - fn left_lower_bound() { - let evp = init_envelope(); - assert!(evp.contains(1600, 100)); + /// Returns the four corner points starting from the lower left point going in clockwise direction. + fn points(&self) -> [Vector2; 4] { + let dy = Vector2::new(0.0, self.max.y - self.min.y); + [self.min, self.min + dy, self.max, self.max - dy] } - #[test] - fn y_below_envelope() { - let evp = init_envelope(); - assert!(!evp.contains(1600, 99.9)); + /// Iterates over the four sides of the rectangle starting from the left vertical segment in clockwise direction. + fn segments(&self) -> impl Iterator + '_ { + let points = self.points(); + (0..4).map(move |i| (points[i], points[(i + 1) % 4]).into()) } + /// Determines whether the specified point is within or on the reactangle. + fn contains(&self, point: Vector2) -> bool { + (self.min.x <= point.x && point.x <= self.max.x) + && (self.min.y <= point.y && point.y <= self.max.y) + } + + /// Determines whether the specified point is on the rectangle boundary. + fn is_point_on_boundary(&self, point: Vector2) -> bool { + if !self.contains(point) { + return false; + } + + point.x == self.min.x + || point.x == self.max.y + || point.y == self.min.y + || point.y == self.max.y + } +} + +/// Represents a line segment. +#[derive(Copy, Clone, Default, Debug, PartialEq)] +pub struct LineSegment { + /// First point which defines the line segment. + point1: Vector2, + /// Second point which defines the line segment. + point2: Vector2, +} + +impl LineSegment { + /// Create a new line segment. + fn new(p1: Vector2, p2: Vector2) -> Self { + Self { + point1: p1, + point2: p2, + } + } + + /// Returns the mid point of the line segment. + fn mid(&self) -> Vector2 { + self.point1 + 0.5 * (self.point2 - self.point1) + } + + /// Determines whether the specified point is on the line segment. + fn contains(&self, point: Vector2) -> bool { + let ab = self.point2 - self.point1; + let ac = point - self.point1; + + if ab.magnitude() == 0.0 { + return point == self.point1; + } + + let cross_prod = (ab.x * ac.y) - (ac.x * ab.y); + if cross_prod != 0.0 { + return false; + } + + let ab_dot_ac = (ab.x * ac.x) + (ab.y * ac.y); + if ab_dot_ac < 0.0 { + return false; + } else if ab_dot_ac == 0.0 { + return true; + } + + let ab_dot_ab = (ab.x * ab.x) + (ab.y * ab.y); + if ab_dot_ac > ab_dot_ab { + return false; + } else if ab_dot_ac == ab_dot_ab { + return true; + } + + true + } + + /// Translates the line segment by the specified offset. + fn translate(&self, offset: Vector2) -> LineSegment { + (self.point1 + offset, self.point2 + offset).into() + } +} + +impl From<(Vector2, Vector2)> for LineSegment { + fn from(segment: (Vector2, Vector2)) -> Self { + Self::new(segment.0, segment.1) + } +} + +impl From for (Vector2, Vector2) { + fn from(segment: LineSegment) -> Self { + (segment.point1, segment.point2) + } +} + +#[cfg(test)] +mod tests { + use nalgebra::Vector2; + + use super::*; + #[test] - fn high_x_in_envelope() { - let evp = init_envelope(); - assert!(evp.contains(1e100, 100)); + fn test_segment_contains() { + let l: LineSegment = (Vector2::zeros(), Vector2::new(100.0, 100.0)).into(); + assert!(l.contains(Vector2::zeros())); + assert!(l.contains(Vector2::new(50.0, 50.0))); + assert!(!l.contains(Vector2::new(101.0, 101.0))); + + let l: LineSegment = (Vector2::new(10.0, 10.0), Vector2::new(10.0, 10.0)).into(); + assert!(l.contains(Vector2::new(10.0, 10.0))); + assert!(!l.contains(Vector2::new(9.0, 9.0))); + assert!(!l.contains(Vector2::zeros())) } #[test] - fn y_above_envelope() { - let evp = init_envelope(); - assert!(!evp.contains(10100, 1959)); + fn test_polygon_contains() { + let points = [ + Vector2::zeros(), + Vector2::new(0.0, 100.0), + Vector2::new(100.0, 100.0), + Vector2::new(100.0, 0.0), + ]; + let poly = Polygon::try_new(points).unwrap(); + + assert!(points.iter().all(|point| poly.contains(*point))); + assert!(poly + .segments() + .map(|segment| segment.mid()) + .all(|point| poly.contains(point))); + + assert!(!poly.contains(Vector2::new(-0.01, -0.01))); + assert!(!poly.contains(Vector2::new(-0.01, 100.01))); + assert!(!poly.contains(Vector2::new(100.01, 100.01))); + assert!(!poly.contains(Vector2::new(100.01, -0.01))); + + let points = [ + Vector2::new(100.0, 100.0), + Vector2::new(100.0, 200.0), + Vector2::new(150.0, 200.0), + Vector2::new(200.0, 50.0), + Vector2::new(250.0, 200.0), + Vector2::new(300.0, 200.0), + Vector2::new(300.0, 100.0), + ]; + let poly = Polygon::try_new(points).unwrap(); + + assert!(points.iter().all(|point| poly.contains(*point))); + assert!(poly + .segments() + .map(|seg| seg.mid()) + .all(|point| poly.contains(point))); + + assert!(!poly.contains(Vector2::new(200.0, 150.0))); + assert!(poly.contains(Vector2::new(200.0, 75.0))); + + let points = [ + Vector2::new(10.0, 10.0), + Vector2::new(10.0, 10.0), + Vector2::new(10.0, 10.0), + Vector2::new(10.0, 10.0), + ]; + + let poly = Polygon::try_new(points).unwrap(); + assert!(points.iter().all(|point| poly.contains(*point))); + assert!(poly + .segments() + .map(|seg| seg.mid()) + .all(|point| poly.contains(point))); + + assert!(!poly.contains(Vector2::new(9.0, 9.0))); + assert!(!poly.contains(Vector2::zeros())); } #[test] - #[should_panic(expected = "called `Option::unwrap()` on a `None` value")] - fn input_list_too_small() { - let evp = Envelope::<1>::new([(0, 0)]).unwrap(); + fn test_envelope() { + let limits = Rect { + min: Vector2::zeros(), + max: Vector2::new(100.0, 100.0), + }; + + let points = [ + Vector2::new(10.0, 0.0), + Vector2::new(10.0, 75.0), + Vector2::new(100.0, 75.0), + ]; + + let envelope = Envelope::try_new(limits, points).unwrap(); + + assert!(envelope.is_within_limits(Vector2::zeros())); + assert!(envelope.is_within_limits(Vector2::new(100.0, 100.0))); + assert!(envelope.is_within_limits(Vector2::new(0.0, 100.0))); + assert!(envelope.is_within_limits(Vector2::new(100.0, 0.0))); + assert!(!envelope.is_within_limits(Vector2::new(150.0, 150.0))); + + assert!(!envelope.contains(Vector2::zeros()).unwrap()); + assert!(!envelope.contains(Vector2::new(100.0, 100.0)).unwrap()); + assert!(envelope.contains(Vector2::new(50.0, 50.0)).unwrap()); + assert!(envelope.contains(Vector2::new(150.0, 150.0)) == Err(())); } } diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index cb4f90e..b8045b9 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -10,25 +10,73 @@ #![no_std] #![deny(unsafe_code)] +#![allow(dead_code)] -pub use alerts::{functionalities, Alert, AlertLevel, AlertState}; -use prelude::*; -pub use types::*; +extern crate enum_map; +#[cfg(test)] #[macro_use] -pub mod macros; +extern crate std; -mod alerts; +pub mod aircraft_state; +pub mod alerts; mod envelope; -pub mod prelude; -mod types; - -pub trait Taws { - fn is_armed(&self, alert_system: Alert) -> bool; - fn arm(&mut self, alert_system: Alert); - fn disarm(&mut self, alert_system: Alert); - fn is_inhibited(&self, alert_system: Alert) -> bool; - fn inhibit(&mut self, alert_system: Alert); - fn uninhibit(&mut self, alert_system: Alert); - fn process(&mut self, state: &AircraftState) -> AlertState; + +pub use aircraft_state::{AircraftState, NormalizedAircraftState}; +pub use alerts::{Alert, AlertLevel, AlertSource}; + +/// Abstraction for a TAWS system +pub trait Taws { + /// Alert set type + type Alerts: TawsAlerts + Default; + + //fn arm(&mut self, alert_src: AlertSource); + //fn disarm(&mut self, alert_src: AlertSource); + + /// Returns whether the specified alert source (TAWS functionallity) is currently armed. + /// # Arguments + /// * `alert_src` - The alert source of which the armed state is returned. + fn is_armed(&self, alert_src: AlertSource) -> bool; + + /// Inhibits the output of the specified alert source. + /// # Arguements + /// * `alert_src` - The alert source to inhibit. + fn inhibit(&mut self, alert_src: AlertSource); + + /// Un-inhibits the output of the specified alert source. + /// # Arguements + /// * `alert_src` - The alert source to un-inhibit. + fn uninhibit(&mut self, alert_src: AlertSource); + + /// Returns whether the specified alert source is currently inhibited. + /// # Arguments + /// * `alert_src` - The alert source of which the inhibit state is returned. + fn is_inhibited(&self, alert_src: AlertSource) -> bool; + + /// Processes an normalized [AircraftState] and + /// returns an alert for each alert source if the related conditions for this TAWS functionallity are given. + /// # Arguments + /// * `state` - The normalized [AircraftState] to process. + fn process(&mut self, state: NormalizedAircraftState) -> Self::Alerts; +} + +/// Abstraction for a TAWS alert +pub trait TawsAlert: Into<(AlertSource, AlertLevel)> + Eq { + /// Returns the TAWS functionallity which emitted this alert + fn source(&self) -> AlertSource; + + /// Returns the alert level of this alert + fn level(&self) -> AlertLevel; +} + +/// Abstraction for a set of TAWS alerts +pub trait TawsAlerts { + /// Alert type + type Alert: TawsAlert; + + /// Returns whether an alert from the given source with at least the specified alert level is active. + /// # Arguments + /// * `alert_src` - The alert source (TAWS functionallity) to check for + /// * `min_level` - The inclusive min level to check for + fn is_alert_active(&self, alert_src: AlertSource, min_level: AlertLevel) -> bool; } diff --git a/opentaws/src/macros.rs b/opentaws/src/macros.rs deleted file mode 100644 index d918b95..0000000 --- a/opentaws/src/macros.rs +++ /dev/null @@ -1,38 +0,0 @@ -// A helper macro to implement the boring part of all AlertSystems -macro_rules! arm_inhibit { - () => { - fn is_armed(&self) -> bool { - self.armed - } - - fn arm(&mut self) { - self.armed = true; - } - - fn disarm(&mut self) { - self.armed = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - }; -} - -macro_rules! armed_return { - ($self:expr, $result:expr) => { - if $self.is_armed() { - $result - } else { - None - } - }; -} diff --git a/opentaws/src/prelude.rs b/opentaws/src/prelude.rs deleted file mode 100644 index 62a8d45..0000000 --- a/opentaws/src/prelude.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! The prelude is a collection of all traits and commonly used types in this crate -//! -//! For normal use of this crate it is sufficient to glob import only this moduel, e.g. `use -//! opentaws::prelude::*`. - -pub use crate::{ - alerts::{functionalities, Alert, Alert::*, AlertLevel, AlertState, AlertSystem}, - types::{AircraftState, TawsConfig}, - Taws, -}; - -#[macro_use] -pub use crate::macros::*; - -pub use uom::si::{ - acceleration::foot_per_second_squared, - angle::degree, - f64::*, - length::foot, - time::second, - velocity::{foot_per_minute, knot}, -}; diff --git a/opentaws/src/signal_test.rs b/opentaws/src/signal_test.rs deleted file mode 100644 index e8ddef9..0000000 --- a/opentaws/src/signal_test.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! This file shall provide filtering - -use crate::prelude::*; -use ringbuffer::{AllocRingBuffer, RingBuffer}; -use uom::si::ratio::{ratio, Ratio}; - -// TODO: What is wrong, if two values do not fit together? -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum UnplausibleSignal { - AltitudeGround, - AltitudeSea, - SpeedAir, - SpeedGround, - NotEnoughData, - //InternalError, - /// Time stamp is either equally aged or older than the last - Anachronistic, -} - -#[derive(Debug)] -pub struct SignalTest { - states: AllocRingBuffer, -} - -impl SignalTest { - pub fn new(config: &TAWSConfig) -> Self { - Self { - states: AllocRingBuffer::with_capacity(16), - } - } - - pub fn check( - &mut self, - aircraft_state: AircraftState, - ) -> Result { - // push new aircraft states - self.states.push(aircraft_state); - - // check if enough aircraft states where gathered - if self.states.len() < self.states.capacity() { - return Err(UnplausibleSignal::NotEnoughData); - } - - // check if the new aircraft state goes forward in time - let dt = self.states.get(-2).unwrap().timestamp - self.states.get(-1).unwrap().timestamp; - if Time::new::(0.0) >= dt { - return Err(UnplausibleSignal::Anachronistic); - } - - let last_state = self.states.get(-2).unwrap(); - let current_state = self.states.get(-1).unwrap(); - - // check if altitude ground is negative - if current_state.altitude_ground < Length::new::(0.0) { - return Err(UnplausibleSignal::AltitudeGround); - } - - // check if height change is plausible - let max_speed = last_state.speed_ground.max(current_state.speed_ground); - let d_altitude = current_state.altitude - last_state.altitude; - //if d_altitude > Ratio::new::(1.5) * dt * max_speed { - // return Err(UnplausibleSignal::AltitudeSea); - //} - - Ok(self.states.get(-1).unwrap().clone()) - } -} diff --git a/opentaws/src/terrain_server.rs b/opentaws/src/terrain_server.rs deleted file mode 100644 index 0f583a0..0000000 --- a/opentaws/src/terrain_server.rs +++ /dev/null @@ -1,32 +0,0 @@ -use core::convert::{From,Into}; - -use crate::prelude::*; - - -pub trait TerrainServer { - fn elevation>(&self, position:T)->Length; - fn nearest_runway>(&self, position:T)->Runway; -} - -pub struct Position { - latitude: Angle, - longitude: Angle, - altitude_sea: Length, -} - -impl From<&AircraftState> for Position { - fn from(aircraft_state: AircraftState)->Self{ - Position{ - longitude: aircraft_state.longitude, - latitude: aircraft_state.latitude, - altitude_sea: aircraft_state.altitude_sea, - } - } -} - -pub struct Runway { - location: Position, - length: Length, - name: String, - azimuth: Angle, -} \ No newline at end of file diff --git a/opentaws/src/types.rs b/opentaws/src/types.rs deleted file mode 100644 index 7c10399..0000000 --- a/opentaws/src/types.rs +++ /dev/null @@ -1,222 +0,0 @@ -use core::{ - fmt, - iter::Empty, - ops::{Add, Rem}, -}; - -use uom::{ - fmt::DisplayStyle::Abbreviation, - si::f64::*, - si::{ - acceleration::foot_per_second_squared, - angle::{degree, revolution}, - length::foot, - time::second, - velocity::{foot_per_minute, knot}, - }, -}; - -use aviation_database::{reference::AirportDatabaseImpl, AirportDatabase, Position, Runway}; - -/// Represents the current state of an aircraft -#[derive(Clone, Debug, Default)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AircraftState { - /// Time when this aircraft state was emitted - pub timestamp: Time, - - /// Height above sea level in foot - pub altitude: Length, - - /// Height above current terrain in foot - pub altitude_ground: Length, - - /// Rate of descent - pub climb_rate: Velocity, - - /// Geographic Latitude, specifying the north-south position - pub position_lat: Angle, - - /// Geographic Longitude, specifying the east-west position - pub position_lon: Angle, - - /// Angle in degrees (clockwise) between north and the direction to the - /// destination or nav aid - //pub bearing: degree, - - /// Aircraft speed as measured by GPS - pub speed_ground: Velocity, - - /// Airspeed as measured by pressure sensors - pub speed_air: Velocity, - - /// Angle in degrees (clockwise) between north and the direction where the - /// aircrafts nose is pointing - pub heading: Angle, - - /// The angle on the pitch axis. A positive value means the aircraft's nose points upwards - /// compared to the horizon. - pub pitch: Angle, - - /// The angle on the roll axis. A positive value means the aircraft's left wing points upwards - /// while the right wing points downwards compared to the horizon. Another way of phrasing it: - /// a positive value means the aircraft is rotated clockwise (as seen from behind). - pub roll: Angle, - - /// Whether steep approach is selected - pub steep_approach: bool, - - /// Whether precision approach is selected - pub precision_approach: bool, - - /// Whether go around is selected - pub go_around: bool, - - /// Whether take-off is selected - pub take_off: bool, -} - -/// This configuration holds various details about the aircraft in use. These are necessary for -/// example when estimating path trajectories for FLTA. -/// -/// TODO adjust doc string to reflect the existence of terrainserver -#[derive(Clone, Debug)] -pub struct TawsConfig<'a> { - pub terrain_server: &'a dyn AirportDatabase>, - - pub max_climbrate: Velocity, - pub max_climbrate_change: Acceleration, -} - -impl AircraftState { - /// Normalizes an `AircraftState`. Only normalized `AircraftStates` should be fed to the TAWS. - pub(crate) fn normalize(&mut self) { - let one_revolution = Angle::new::(1.0); - let half_revolution = Angle::new::(0.5); - let quarter_revolution = Angle::new::(0.25); - - self.heading = Self::modulo(self.heading, one_revolution); - - self.roll = Self::modulo(self.roll + half_revolution, one_revolution) - half_revolution; - self.pitch = Self::modulo(self.pitch + half_revolution, one_revolution) - half_revolution; - - self.position_lat = Self::modulo(self.position_lat + quarter_revolution, half_revolution) - - quarter_revolution; - self.position_lon = - Self::modulo(self.position_lon + half_revolution, one_revolution) - half_revolution; - } - - pub(crate) fn check(&self) { - let zero = Angle::new::(0.0); - let one_revolution = Angle::new::(1.0); - let half_revolution = Angle::new::(0.5); - let quarter_revolution = Angle::new::(0.25); - - (zero..=one_revolution).contains(&self.heading); - - (-half_revolution..=half_revolution).contains(&self.roll); - (-half_revolution..=half_revolution).contains(&self.pitch); - - (-quarter_revolution..=quarter_revolution).contains(&self.position_lat); - (-half_revolution..=half_revolution).contains(&self.position_lon); - } - - fn modulo + Rem>(a: T, b: T) -> T { - ((a % b) + b) % b - } - - pub fn position(&self) -> Position { - Position { - lat: self.position_lat, - lon: self.position_lon, - alt: self.altitude_ground, - } - } -} - -impl fmt::Display for AircraftState { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let s = Time::format_args(second, Abbreviation); - let ft = Length::format_args(foot, Abbreviation); - let dg = Angle::format_args(degree, Abbreviation); - let fpm = Velocity::format_args(foot_per_minute, Abbreviation); - let kt = Velocity::format_args(knot, Abbreviation); - - write!( - f, - "AircrafState: - timestamp: {timestamp:.4} - altitude_sea: {altitude_sea:.2} - altitude_ground: {altitude_ground:.2} - climb_rate: {climb_rate:.2} - position_lat: {position_lat:.7} - position_lon: {position_lon:.7} - heading: {heading:.2} - speed: {speed:.2} - pitch_angle: {pitch_angle:.2} - roll_angle: {roll_angle:.2} - steep_approach: {steep_approach}\n", - timestamp = s.with(self.timestamp), - altitude_sea = ft.with(self.altitude), - altitude_ground = ft.with(self.altitude_ground), - climb_rate = fpm.with(self.climb_rate), - position_lat = dg.with(self.position_lat), - position_lon = dg.with(self.position_lon), - heading = dg.with(self.heading), - speed = kt.with(self.speed_ground), - pitch_angle = dg.with(self.pitch), - roll_angle = dg.with(self.roll), - steep_approach = self.steep_approach, - ) - } -} - -impl<'a> Default for TawsConfig<'a> { - fn default() -> Self { - static AIRPORT_DATABASE: AirportDatabaseImpl = AirportDatabaseImpl {}; - Self { - terrain_server: &AIRPORT_DATABASE, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - use uom::si::length::foot; - - const EPS: f64 = 1e-10; - - #[test] - fn negative_altitude() { - let mut state = AircraftState::default(); - state.altitude_ground = Length::new::(-12.0); - } - - #[test] - fn normalize_angle_below_zero() { - let mut aircraft_state = AircraftState::default(); - aircraft_state.heading = Angle::new::(-1.0); - aircraft_state.normalize(); - assert_eq!(aircraft_state.heading, Angle::new::(359.0)); - } - - #[test] - fn normalize_angle_far_below_zero() { - let mut aircraft_state = AircraftState::default(); - aircraft_state.heading = Angle::new::(-1024.0); - aircraft_state.normalize(); - assert!((aircraft_state.heading - Angle::new::(56.0)).get::() < EPS); - } - - #[test] - fn normalize_angle_far_above_zero() { - let mut aircraft_state = AircraftState::default(); - aircraft_state.heading = Angle::new::(1024.0); - aircraft_state.normalize(); - assert!((aircraft_state.heading - Angle::new::(304.0)).get::() < EPS); - } -} From ca3932ae087c5175bc2e1baad27459d869be778c Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 11 Oct 2022 13:38:00 +0200 Subject: [PATCH 48/73] rework opentaws implementation --- opentaws/src/alerts.rs | 16 +++-- opentaws/src/alerts/ffac.rs | 78 ++++++++++++++++++++++ opentaws/src/alerts/mode1.rs | 122 +++++++++++++++++++++++++++++++++++ opentaws/src/alerts/mode3.rs | 111 +++++++++++++++++++++++++++++++ opentaws/src/alerts/pda.rs | 86 ++++++++++++++++++++++++ opentaws/src/envelope.rs | 87 ++++++++++++------------- opentaws/src/lib.rs | 43 ++++++++++-- 7 files changed, 489 insertions(+), 54 deletions(-) create mode 100644 opentaws/src/alerts/ffac.rs create mode 100644 opentaws/src/alerts/mode1.rs create mode 100644 opentaws/src/alerts/mode3.rs create mode 100644 opentaws/src/alerts/pda.rs diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index b4d88df..4ed9083 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,3 +1,8 @@ +pub mod ffac; +pub mod mode1; +pub mod mode3; +pub mod pda; + use crate::{TawsAlert, TawsAlerts}; use enum_map::{Enum, EnumMap}; @@ -56,6 +61,12 @@ pub struct Alert { pub level: AlertLevel, } +impl Alert { + pub fn new(source: AlertSource, level: AlertLevel) -> Self { + Alert { source, level } + } +} + impl TawsAlert for Alert { fn source(&self) -> AlertSource { self.source @@ -68,10 +79,7 @@ impl TawsAlert for Alert { impl From<(AlertSource, AlertLevel)> for Alert { fn from(alert: (AlertSource, AlertLevel)) -> Self { - Alert { - source: alert.0, - level: alert.1, - } + Self::new(alert.0, alert.1) } } diff --git a/opentaws/src/alerts/ffac.rs b/opentaws/src/alerts/ffac.rs new file mode 100644 index 0000000..739817d --- /dev/null +++ b/opentaws/src/alerts/ffac.rs @@ -0,0 +1,78 @@ +use crate::{aircraft_state::FlightSegment, Alert, AlertLevel, AlertSource, TawsFunctionality}; + +use uom::{ + num_traits::Zero, + si::{f64::Length, length::foot}, +}; + +pub struct Ffac { + alert_src: AlertSource, + armed: bool, + inhibited: bool, + + last_altitude: Length, +} + +impl Default for Ffac { + fn default() -> Self { + Self { + alert_src: AlertSource::Ffac, + armed: true, + inhibited: false, + last_altitude: Length::zero(), + } + } +} + +impl TawsFunctionality for Ffac { + type Alert = Alert; + + fn alert_source(&self) -> AlertSource { + self.alert_src + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: crate::NormalizedAircraftState, + ) -> Result, ()> { + let armed = state + .situation() + .map(|s| !matches!(s, FlightSegment::TakeOff | FlightSegment::GoAround)) + .ok_or(())?; + + self.armed = armed; + if !self.armed { + return Ok(None); + } + + let fivehundred = Length::new::(500.0); + let result: Result, ()> = + if self.last_altitude >= fivehundred && state.altitude_ground() < fivehundred { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Annunciation))) + } else { + Ok(None) + }; + + if !self.inhibited { + result + } else { + Ok(None) + } + } +} diff --git a/opentaws/src/alerts/mode1.rs b/opentaws/src/alerts/mode1.rs new file mode 100644 index 0000000..093e7ce --- /dev/null +++ b/opentaws/src/alerts/mode1.rs @@ -0,0 +1,122 @@ +use crate::{ + aircraft_state::FlightSegment, + envelope::{Envelope, INVALID_ENVELOPE}, + Alert, AlertLevel, AlertSource, TawsFunctionality, +}; +use lazy_static::lazy_static; +use nalgebra::Vector2; +use uom::si::{length::foot, velocity::foot_per_minute}; + +#[derive(Clone, Debug)] +pub struct Mode1 { + alert_src: AlertSource, + armed: bool, + inhibited: bool, +} + +impl Default for Mode1 { + fn default() -> Self { + Self { + alert_src: AlertSource::Mode1, + armed: true, + inhibited: false, + } + } +} + +impl TawsFunctionality for Mode1 { + type Alert = Alert; + + fn alert_source(&self) -> AlertSource { + self.alert_src + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: crate::NormalizedAircraftState, + ) -> Result, ()> { + let altitude = state.altitude_ground().get::(); + let rod = -state.climb_rate().get::(); + let steep_approach = state + .situation() + .map(|s| match s { + FlightSegment::Landing { steep_approach, .. } => *steep_approach, + _ => false, + }) + .ok_or(())?; + + let result = match steep_approach { + true if STEEP_WARNING_ENVELOPE.contains(rod, altitude)? => { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Warning))) + } + true if STEEP_CAUTION_ENVELOPE.contains(rod, altitude)? => { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) + } + false if WARNING_ENVELOPE.contains(rod, altitude)? => { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Warning))) + } + false if CAUTION_ENVELOPE.contains(rod, altitude)? => { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) + } + _ => Err(()), + }; + + if !self.inhibited { + result + } else { + Ok(None) + } + } +} + +lazy_static! { + static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::try_new([ + Vector2::new(100_000.0, 100.0), + Vector2::new(1560.0, 100.0), + Vector2::new(2200.0, 630.0), + Vector2::new(5700.0, 2200.0), + Vector2::new(100_000.0, 2200.0) + ]) + .expect(INVALID_ENVELOPE); + static ref STEEP_CAUTION_ENVELOPE: Envelope<6> = Envelope::try_new([ + Vector2::new(100_000.0, 150.0), + Vector2::new(1798.0, 150.0), + Vector2::new(1944.0, 300.0), + Vector2::new(3233.0, 1078.0), + Vector2::new(6225.0, 2075.0), + Vector2::new(100_000.0, 2075.0) + ]) + .expect(INVALID_ENVELOPE); + static ref WARNING_ENVELOPE: Envelope<5> = Envelope::try_new([ + Vector2::new(100_000.0, 100.0), + Vector2::new(1600.0, 100.0), + Vector2::new(1850.0, 300.0), + Vector2::new(10100.0, 1958.0), + Vector2::new(100_000.0, 1958.0) + ]) + .expect(INVALID_ENVELOPE); + static ref STEEP_WARNING_ENVELOPE: Envelope<5> = Envelope::try_new([ + Vector2::new(100_000.0, 150.0), + Vector2::new(1908.0, 150.0), + Vector2::new(2050.0, 300.0), + Vector2::new(10300.0, 1958.0), + Vector2::new(100_000.0, 1958.0) + ]) + .expect(INVALID_ENVELOPE); +} diff --git a/opentaws/src/alerts/mode3.rs b/opentaws/src/alerts/mode3.rs new file mode 100644 index 0000000..d5d5578 --- /dev/null +++ b/opentaws/src/alerts/mode3.rs @@ -0,0 +1,111 @@ +use crate::{ + aircraft_state::FlightSegment, + envelope::{Envelope, INVALID_ENVELOPE}, + Alert, AlertLevel, AlertSource, TawsFunctionality, +}; +use lazy_static::lazy_static; +use nalgebra::Vector2; +use uom::{ + num_traits::Zero, + si::{f64::Length, length::foot, velocity::foot_per_minute}, +}; + +pub struct Mode3 { + alert_src: AlertSource, + armed: bool, + inhibited: bool, + + max_altitude_ground: Length, +} + +impl Default for Mode3 { + fn default() -> Self { + Self { + alert_src: AlertSource::Mode3, + armed: false, + inhibited: false, + + max_altitude_ground: Length::zero(), + } + } +} + +impl TawsFunctionality for Mode3 { + type Alert = Alert; + + fn alert_source(&self) -> AlertSource { + self.alert_src + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: crate::NormalizedAircraftState, + ) -> Result, ()> { + let armed = state + .situation() + .map(|s| matches!(s, FlightSegment::TakeOff | FlightSegment::GoAround)) + .ok_or(())?; + + if let (false, true) = (self.armed, armed) { + self.max_altitude_ground = state.altitude_ground() + } + + self.armed = armed; + if !self.armed { + return Ok(None); + } + + self.max_altitude_ground = Length::max(self.max_altitude_ground, state.altitude_ground()); + + let alt_loss = (self.max_altitude_ground - state.altitude_ground()).get::(); + let altitude = state.altitude_ground().get::(); + let rod = -state.climb_rate().get::(); + + let result = if METHODE_1_CAUTION_ENVELOPE.contains(rod, altitude)? + || METHODE_2_CAUTION_ENVELOPE.contains(alt_loss, altitude)? + { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) + } else { + Ok(None) + }; + + if !self.inhibited { + result + } else { + Ok(None) + } + } +} + +lazy_static! { + static ref METHODE_1_CAUTION_ENVELOPE: Envelope::<4> = Envelope::try_new([ + Vector2::new(100_000.0, 60.0), + Vector2::new(207.0, 60.0), + Vector2::new(533.0, 600.0), + Vector2::new(100_000.0, 600.0) + ]) + .expect(INVALID_ENVELOPE); + static ref METHODE_2_CAUTION_ENVELOPE: Envelope::<4> = Envelope::try_new([ + Vector2::new(100_000.0, 60.0), + Vector2::new(26.0, 60.0), + Vector2::new(80.0, 600.0), + Vector2::new(100_000.0, 600.0) + ]) + .expect(INVALID_ENVELOPE); +} diff --git a/opentaws/src/alerts/pda.rs b/opentaws/src/alerts/pda.rs new file mode 100644 index 0000000..775e495 --- /dev/null +++ b/opentaws/src/alerts/pda.rs @@ -0,0 +1,86 @@ +use crate::{ + envelope::{Envelope, INVALID_ENVELOPE}, + Alert, AlertLevel, AlertSource, TawsFunctionality, +}; +use lazy_static::lazy_static; +use nalgebra::Vector2; +use uom::si::length::foot; + +pub struct PDA { + alert_src: AlertSource, + armed: bool, + inhibited: bool, +} + +impl Default for PDA { + fn default() -> Self { + Self { + alert_src: AlertSource::Pda, + armed: false, + inhibited: false, + } + } +} + +impl TawsFunctionality for PDA { + type Alert = Alert; + + fn alert_source(&self) -> AlertSource { + self.alert_src + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: crate::NormalizedAircraftState, + ) -> Result, ()> { + // ToDo + let altitude_gnd_foot = state.altitude_ground().get::(); + let distance_to_nearest_airport_nm = 3.0; + + self.armed = distance_to_nearest_airport_nm <= 5.0; + if !self.armed { + return Ok(None); + } + + let result: Result, ()> = + if CAUTION_ENVELOPE.contains(distance_to_nearest_airport_nm, altitude_gnd_foot)? { + Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) + } else { + Ok(None) + }; + + if !self.inhibited { + result + } else { + Ok(None) + } + } +} + +lazy_static! { + static ref CAUTION_ENVELOPE: Envelope::<6> = Envelope::try_new([ + Vector2::new(5.0, 10.0), + Vector2::new(1.0, 10.0), + Vector2::new(1.0, 80.0), + Vector2::new(1.8, 150.0), + Vector2::new(2.3, 170.0), + Vector2::new(5.0, 170.0) + ]) + .expect(INVALID_ENVELOPE); +} diff --git a/opentaws/src/envelope.rs b/opentaws/src/envelope.rs index f21f66e..1f862bb 100644 --- a/opentaws/src/envelope.rs +++ b/opentaws/src/envelope.rs @@ -1,53 +1,52 @@ type Vector2 = nalgebra::Vector2; +pub const INVALID_ENVELOPE: &str = "Invalid Envelope!"; + /// Represents a TAWS Envelope which defines under what conditions an alert should and should not be emitted. pub struct Envelope { - /// Defines the operating limits of this envelope.
+ /*/// Defines the operating limits of this envelope.
/// For states outside these limits the envelope is not defined. - limits: Rect, - /// Defines the conditions under which an alert should or should not be emitted.
- /// The start and end point must coincide with the envelope limits. - /// The other points must be inside of the envelope limits. + limits: Rect, */ + /// Defines the conditions under which an alert should or should not be emitted. polygon: Polygon, } impl Envelope { /// Creates a new Envelope from the given envelope limits and polygon points. /// # Arguments - /// * `limits` - the limits of the envelope in which the envelope is defined. Must be finite. /// * `points` - the polygon points which define the envelope. At least 3 points are nessecary. All points must be finite. /// ToDO (maybe): Augment the polygon to the envelope limits by adding a new start point and new end points to close the polygon with the envelope limits. - pub fn try_new(limits: Rect, points: [Vector2; N]) -> Result { - if !Self::are_valid_limits(&limits) { + pub fn try_new(/* limits: Rect, */ points: [Vector2; N]) -> Result { + /*if !Self::are_valid_limits(&limits) { return Err(()); - } + }*/ - if !Self::are_points_valid(&limits, &points) { + if !Self::are_points_valid(/* &limits, */ &points) { return Err(()); } Ok(Self { - limits, + //limits, polygon: Polygon::try_new(points)?, }) } - /// checks wether the given limits are sufficent for an envelope. + /* /// checks wether the given limits are sufficent for an envelope. fn are_valid_limits(limits: &Rect) -> bool { limits.min.x.is_finite() && limits.min.y.is_finite() && limits.max.x.is_finite() && limits.max.y.is_finite() - } + } */ /// checks whether the given polygon points are sufficent for an envelope. /// the polygon must start and end on the envelope limits. all in-between points must be within the envelope limit. - fn are_points_valid(limits: &Rect, points: &[Vector2; N]) -> bool { + fn are_points_valid(/* limits: &Rect, */ _points: &[Vector2; N]) -> bool { if N < 3 { return false; } - let first_point = points.first().unwrap(); + /* let first_point = points.first().unwrap(); let last_point = points.last().unwrap(); if !limits.is_point_on_boundary(*first_point) || !limits.is_point_on_boundary(*last_point) { return false; @@ -56,32 +55,32 @@ impl Envelope { let mid_points = &points[1..N - 1]; if !mid_points.iter().all(|point| limits.contains(*point)) { return false; - } + } */ true } - /// Returns whether the envelope is defined for the specified point. + /* /// Returns whether the envelope is defined for the specified point. /// # Arguments /// * `point` - The point which is tested /// # Returns /// * `true` if the given point is within the envelope limits; otherwise `false`. pub fn is_within_limits(&self, point: Vector2) -> bool { self.limits.contains(point) - } + } */ - /// Determines whether the specified state is within the envelope. + /// Determines whether the specified (x, y) state is within the envelope. /// # Arguments - /// * `point` - The state which is tested against the envelope. + /// * `x` - The first state component. + /// * `y` - The second state compoenent. /// # Returns - /// * `Ok(bool)` - Indicates whether the given point is within the envelope. - /// * `Err()` - The given point is not within the envelope limits. - pub fn contains(&self, point: Vector2) -> Result { - if !self.is_within_limits(point) { + /// * `Ok(bool)` - Indicates whether the given state is within the envelope. + pub fn contains(&self, x: f64, y: f64) -> Result { + /* if !self.is_within_limits(point) { return Err(()); - } + } */ - Ok(self.polygon.contains(point)) + Ok(self.polygon.contains(Vector2::new(x, y))) } } @@ -119,7 +118,7 @@ impl Polygon { &self.points } - /// returns the axis-aligned bounding-box for the polygon. + /* /// returns the axis-aligned bounding-box for the polygon. fn bounding_box(&self) -> Rect { let mut min = Vector2::new(f64::INFINITY, f64::INFINITY); let mut max = Vector2::new(f64::NEG_INFINITY, f64::NEG_INFINITY); @@ -139,7 +138,7 @@ impl Polygon { } Rect::new(min, max) - } + } */ /// returns an iterator over fn segments(&self) -> impl Iterator + '_ { @@ -188,9 +187,9 @@ impl Polygon { } } -/// Represents an axis-aligned rectangle. +/* /// Represents an axis-aligned rectangle. #[derive(Copy, Clone, Default, Debug, PartialEq)] -pub struct Rect { +struct Rect { /// lower left corner min: Vector2, /// upper right corner @@ -235,7 +234,7 @@ impl Rect { || point.y == self.min.y || point.y == self.max.y } -} +} */ /// Represents a line segment. #[derive(Copy, Clone, Default, Debug, PartialEq)] @@ -248,7 +247,7 @@ pub struct LineSegment { impl LineSegment { /// Create a new line segment. - fn new(p1: Vector2, p2: Vector2) -> Self { + pub fn new(p1: Vector2, p2: Vector2) -> Self { Self { point1: p1, point2: p2, @@ -256,12 +255,12 @@ impl LineSegment { } /// Returns the mid point of the line segment. - fn mid(&self) -> Vector2 { + pub fn mid(&self) -> Vector2 { self.point1 + 0.5 * (self.point2 - self.point1) } /// Determines whether the specified point is on the line segment. - fn contains(&self, point: Vector2) -> bool { + pub fn contains(&self, point: Vector2) -> bool { let ab = self.point2 - self.point1; let ac = point - self.point1; @@ -292,7 +291,7 @@ impl LineSegment { } /// Translates the line segment by the specified offset. - fn translate(&self, offset: Vector2) -> LineSegment { + pub fn translate(&self, offset: Vector2) -> LineSegment { (self.point1 + offset, self.point2 + offset).into() } } @@ -389,10 +388,10 @@ mod tests { #[test] fn test_envelope() { - let limits = Rect { + /* let limits = Rect { min: Vector2::zeros(), max: Vector2::new(100.0, 100.0), - }; + }; */ let points = [ Vector2::new(10.0, 0.0), @@ -400,17 +399,17 @@ mod tests { Vector2::new(100.0, 75.0), ]; - let envelope = Envelope::try_new(limits, points).unwrap(); + let envelope = Envelope::try_new(/* limits, */ points).unwrap(); - assert!(envelope.is_within_limits(Vector2::zeros())); + /* assert!(envelope.is_within_limits(Vector2::zeros())); assert!(envelope.is_within_limits(Vector2::new(100.0, 100.0))); assert!(envelope.is_within_limits(Vector2::new(0.0, 100.0))); assert!(envelope.is_within_limits(Vector2::new(100.0, 0.0))); - assert!(!envelope.is_within_limits(Vector2::new(150.0, 150.0))); + assert!(!envelope.is_within_limits(Vector2::new(150.0, 150.0))); */ - assert!(!envelope.contains(Vector2::zeros()).unwrap()); - assert!(!envelope.contains(Vector2::new(100.0, 100.0)).unwrap()); - assert!(envelope.contains(Vector2::new(50.0, 50.0)).unwrap()); - assert!(envelope.contains(Vector2::new(150.0, 150.0)) == Err(())); + assert!(!envelope.contains(0.0, 0.0).unwrap()); + assert!(!envelope.contains(100.0, 100.0).unwrap()); + assert!(envelope.contains(50.0, 50.0).unwrap()); + assert!(envelope.contains(150.0, 150.0) == Err(())); } } diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index b8045b9..4d0872f 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -20,20 +20,25 @@ extern crate std; pub mod aircraft_state; pub mod alerts; -mod envelope; +pub(crate) mod envelope; pub use aircraft_state::{AircraftState, NormalizedAircraftState}; pub use alerts::{Alert, AlertLevel, AlertSource}; /// Abstraction for a TAWS system pub trait Taws { + type Alert: TawsAlert + Sized; /// Alert set type - type Alerts: TawsAlerts + Default; + type Alerts: TawsAlerts + Default; //fn arm(&mut self, alert_src: AlertSource); //fn disarm(&mut self, alert_src: AlertSource); - /// Returns whether the specified alert source (TAWS functionallity) is currently armed. + // ToDo: + //fn functionality(&self) -> Option; + //fn functionalities(&self) -> iterator, array, slice ???; + + /// Returns whether the specified alert source (TAWS functionality) is currently armed. /// # Arguments /// * `alert_src` - The alert source of which the armed state is returned. fn is_armed(&self, alert_src: AlertSource) -> bool; @@ -53,11 +58,37 @@ pub trait Taws { /// * `alert_src` - The alert source of which the inhibit state is returned. fn is_inhibited(&self, alert_src: AlertSource) -> bool; - /// Processes an normalized [AircraftState] and - /// returns an alert for each alert source if the related conditions for this TAWS functionallity are given. + /// Processes a normalized [AircraftState] and + /// returns an alert for each alert source if the related conditions for this TAWS functionality are given. + /// # Arguments + /// * `state` - The normalized [AircraftState] to process. + fn process(&mut self, state: NormalizedAircraftState) -> Self::Alerts; //ToDo: Result ? +} + +/// Represents a TAWS functionality +pub trait TawsFunctionality { + /// Alert type + type Alert: TawsAlert; + + /// Returns the alert source which is controlled by this functionality. + fn alert_source(&self) -> AlertSource; + + /// Returns whether the functionality is armed. + fn is_armed(&self) -> bool; + + /// Inhibits the functionality. + fn inhibit(&mut self); + + /// Un-inhibits the functionality. + fn uninhibit(&mut self); + + /// Returns whether the functionality is currently inhibited. + fn is_inhibited(&self) -> bool; + + /// Processes a normalized [AircraftState] and returns an alert result or an error. /// # Arguments /// * `state` - The normalized [AircraftState] to process. - fn process(&mut self, state: NormalizedAircraftState) -> Self::Alerts; + fn process(&mut self, state: NormalizedAircraftState) -> Result, ()>; // Todo Error type? anyhow, thiserror, snafu, ...?; Return multiple alerts? } /// Abstraction for a TAWS alert From 3f2de8bfc1b241b6f7e9adc9db991ce54c10fca4 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 1 Nov 2022 10:57:08 +0100 Subject: [PATCH 49/73] wip --- Cargo.lock | 1032 ++++++++++++++++- Cargo.toml | 8 +- opentaws/Cargo.toml | 3 +- opentaws/src/aircraft_state.rs | 25 +- opentaws/src/alerts.rs | 304 +++-- opentaws/src/alerts/ffac.rs | 78 -- opentaws/src/alerts/mode1.rs | 122 -- opentaws/src/alerts/mode3.rs | 111 -- opentaws/src/alerts/pda.rs | 86 -- opentaws/src/class_c.rs | 146 +++ opentaws/src/class_c/ffac.rs | 87 ++ opentaws/src/class_c/mode1.rs | 151 +++ opentaws/src/class_c/mode3.rs | 131 +++ opentaws/src/class_c/offset_envelope.ipynb | 161 +++ opentaws/src/class_c/pda.rs | 87 ++ opentaws/src/envelope.rs | 447 ++++--- opentaws/src/lib.rs | 186 ++- opentaws/src/prelude.rs | 16 + rust-toolchain.toml | 3 + taws_minimal/Cargo.toml | 28 +- taws_minimal/examples/flightgear.rs | 132 --- .../features/alert_prioritization.feature | 18 - taws_minimal/features/ffac.feature | 2 +- taws_minimal/features/mode_1.feature | 16 +- taws_minimal/features/mode_3.feature | 18 +- taws_minimal/features/pda.feature | 2 +- taws_minimal/features/self_test.feature | 38 - taws_minimal/src/lib.rs | 332 +----- taws_minimal/src/macros.rs | 36 - taws_minimal/tests/cucumber.rs | 96 +- taws_minimal/tests/util/aircraft_state.rs | 50 +- .../constraints/aircraft_state_constraints.rs | 74 +- .../util/constraints/airport_database.rs | 8 - taws_minimal/tests/util/constraints/mod.rs | 2 - taws_minimal/tests/util/parameters.rs | 67 +- taws_minimal/tests/util/world.rs | 67 +- 36 files changed, 2619 insertions(+), 1551 deletions(-) delete mode 100644 opentaws/src/alerts/ffac.rs delete mode 100644 opentaws/src/alerts/mode1.rs delete mode 100644 opentaws/src/alerts/mode3.rs delete mode 100644 opentaws/src/alerts/pda.rs create mode 100644 opentaws/src/class_c.rs create mode 100644 opentaws/src/class_c/ffac.rs create mode 100644 opentaws/src/class_c/mode1.rs create mode 100644 opentaws/src/class_c/mode3.rs create mode 100644 opentaws/src/class_c/offset_envelope.ipynb create mode 100644 opentaws/src/class_c/pda.rs create mode 100644 opentaws/src/prelude.rs create mode 100644 rust-toolchain.toml delete mode 100644 taws_minimal/examples/flightgear.rs delete mode 100644 taws_minimal/features/alert_prioritization.feature delete mode 100644 taws_minimal/features/self_test.feature delete mode 100644 taws_minimal/src/macros.rs delete mode 100644 taws_minimal/tests/util/constraints/airport_database.rs diff --git a/Cargo.lock b/Cargo.lock index dc6c912..6b9e2ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -32,12 +43,41 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "array-init" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596" +[[package]] +name = "async-trait" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-polyfill" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89" +dependencies = [ + "critical-section", +] + [[package]] name = "atty" version = "0.2.14" @@ -75,12 +115,39 @@ dependencies = [ "ureq", ] +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + [[package]] name = "bitflags" version = "1.3.2" @@ -105,12 +172,24 @@ version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "bytemuck" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "cast" version = "0.3.0" @@ -142,10 +221,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags", - "textwrap", + "textwrap 0.11.0", "unicode-width", ] +[[package]] +name = "clap" +version = "4.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "once_cell", + "strsim", + "termcolor", + "terminal_size 0.2.1", +] + +[[package]] +name = "clap_derive" +version = "4.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "console" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "terminal_size 0.1.17", + "unicode-width", + "winapi", +] + +[[package]] +name = "cortex-m" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "embedded-hal", + "volatile-register", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -163,7 +306,7 @@ checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -191,6 +334,18 @@ dependencies = [ "itertools", ] +[[package]] +name = "critical-section" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" +dependencies = [ + "bare-metal 1.0.0", + "cfg-if", + "cortex-m", + "riscv", +] + [[package]] name = "crossbeam-channel" version = "0.5.6" @@ -259,31 +414,144 @@ dependencies = [ ] [[package]] -name = "either" -version = "1.7.0" +name = "ctor" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn", +] [[package]] -name = "enum-map" -version = "2.4.1" +name = "cucumber" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a56d54c8dd9b3ad34752ed197a4eb2a6601bc010808eb097a04a58ae4c43e1" +checksum = "56264a57a9b7207418f64e09dec7805cd4264b98c762150d3769171fb8a6fee5" dependencies = [ - "enum-map-derive", + "anyhow", + "async-trait", + "atty", + "clap 4.0.18", + "console", + "cucumber-codegen", + "cucumber-expressions", + "derive_more", + "drain_filter_polyfill", + "either", + "futures", + "gherkin", + "globwalk", + "humantime", + "inventory", + "itertools", + "linked-hash-map", + "once_cell", + "regex", + "sealed 0.4.0", ] [[package]] -name = "enum-map-derive" -version = "0.10.0" +name = "cucumber-codegen" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f965514ac959efa875c8b17de1510d521aed75346ced61af1307968aea6f0f92" +dependencies = [ + "cucumber-expressions", + "inflections", + "itertools", + "proc-macro2", + "quote", + "regex", + "syn", + "synthez", +] + +[[package]] +name = "cucumber-expressions" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40d2fdf5e1bb4ae7e6b25c97bf9b9d249a02243fc0fbd91075592b5f00a3bc1" +dependencies = [ + "derive_more", + "either", + "nom", + "nom_locate", + "regex", + "regex-syntax", +] + +[[package]] +name = "derive_arbitrary" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4903dff04948f22033ca30232ab8eca2c3fc4c913a8b6a34ee5199699814817f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9045e2676cd5af83c3b167d917b0a5c90a4d8e266e2683d6631b235c457fc27" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "drain_filter_polyfill" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9f76bdd86dfc8d64eecb0484d02ad4cf0e6767d4682f686d1b0580b6c27f82" + +[[package]] +name = "either" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "flate2" version = "1.0.24" @@ -294,6 +562,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -304,23 +578,210 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "gherkin" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8f8f49b2b547ec22cc4d99f3bf30d4889ef0dbaa231c0736eeaf20efb5a38e" +dependencies = [ + "heck 0.4.0", + "peg", + "quote", + "serde", + "serde_json", + "syn", + "textwrap 0.16.0", + "thiserror", + "typed-builder", +] + +[[package]] +name = "ghost" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "globset" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + [[package]] name = "half" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version 0.4.0", + "spin 0.9.4", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -330,6 +791,12 @@ dependencies = [ "libc", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.2.3" @@ -341,11 +808,51 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "inflections" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" + +[[package]] +name = "inventory" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e21e0a36a4dc4b469422ee17f715e8313f4a637675656d6a13637954278c6f55" +dependencies = [ + "ctor", + "ghost", +] + +[[package]] +name = "io-lifetimes" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e481ccbe3dea62107216d0d1138bb8ad8e5e5c43009a098bd1990272c497b0" + [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -396,7 +903,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -411,6 +918,28 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.17" @@ -450,6 +979,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -479,11 +1014,47 @@ dependencies = [ name = "nalgebra-macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom_locate" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37794436ca3029a3089e0b95d42da1f0b565ad271e4d3bb4bad0c7bb70b10605" dependencies = [ - "proc-macro2", - "quote", - "syn", + "bytecount", + "memchr", + "nom", ] [[package]] @@ -577,7 +1148,8 @@ name = "opentaws" version = "0.1.0" dependencies = [ "aviation_database", - "enum-map", + "hash32", + "heapless", "lazy_static", "nalgebra", "ringbuffer", @@ -595,23 +1167,68 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_str_bytes" +version = "6.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" + [[package]] name = "paste" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +[[package]] +name = "peg" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" + [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "plotters" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -628,9 +1245,9 @@ checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -641,6 +1258,30 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.43" @@ -682,9 +1323,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -760,7 +1401,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -775,6 +1416,59 @@ dependencies = [ "array-init", ] +[[package]] +name = "riscv" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" +dependencies = [ + "bare-metal 1.0.0", + "bit_field", + "riscv-target", +] + +[[package]] +name = "riscv-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.14", +] + +[[package]] +name = "rustix" +version = "0.35.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c825b8aa8010eb9ee99b75f05e10180b9278d161583034d7574c9d617aeada" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" version = "0.20.6" @@ -827,6 +1521,51 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sealed" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636b9882a0f4cc2039488df89a10eb4b7976d4b6c1917fc0518f3f0f5e2c72ca" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sealed" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b5e421024b5e5edfbaa8e60ecf90bda9dbffc602dbb230e6028763f85f0c68c" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.143" @@ -890,12 +1629,48 @@ dependencies = [ "wide", ] +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smawk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.99" @@ -907,6 +1682,84 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synthez" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033178d0acccffc5490021657006e6a8dd586ee9dc6f7c24e7608b125e568cb1" +dependencies = [ + "syn", + "synthez-codegen", + "synthez-core", +] + +[[package]] +name = "synthez-codegen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69263462a40e46960f070618e20094ce69e783a41f86e54bc75545136afd597a" +dependencies = [ + "syn", + "synthez-core", +] + +[[package]] +name = "synthez-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8b5a4089fe1723279f06302afda64a5dacaa11a82bcbb4d08759590d4389d9" +dependencies = [ + "proc-macro2", + "quote", + "sealed 0.3.0", + "syn", +] + +[[package]] +name = "taws_minimal" +version = "0.1.0" +dependencies = [ + "arbitrary", + "aviation_database", + "cucumber", + "futures", + "lazy_static", + "opentaws", + "rand", + "rand_pcg", + "regex", + "uom", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "terminal_size" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8440c860cf79def6164e4a0a983bcc2305d82419177a0e0c71930d049e3ac5a1" +dependencies = [ + "rustix", + "windows-sys", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -916,6 +1769,17 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.37" @@ -936,6 +1800,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -961,6 +1834,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "typenum" version = "1.15.0" @@ -989,6 +1873,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +[[package]] +name = "unicode-linebreak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" +dependencies = [ + "hashbrown", + "regex", +] + [[package]] name = "unicode-normalization" version = "0.1.21" @@ -998,11 +1892,17 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "untrusted" @@ -1049,6 +1949,33 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" +dependencies = [ + "vcell", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -1189,3 +2116,46 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Cargo.toml b/Cargo.toml index 2af263d..19aa074 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] members = [ "opentaws", - #"taws_minimal", - #"aviation_database", - #"kd_tree", - #"kd_tree_sort", + "taws_minimal", + "aviation_database", + "kd_tree", + "kd_tree_sort", ] diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 7e85f9b..508f6c4 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -28,7 +28,8 @@ use-serde = ["uom/use_serde"] [dependencies] aviation_database = { path = "../aviation_database" } lazy_static = { version = "1", features = ["spin_no_std"] } -enum-map = "2.4.1" +heapless = "0.7.16" +hash32 = "0.2.1" nalgebra = { version = "0.31.1", features = ["libm"] } uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 0f218ee..4885658 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -5,17 +5,10 @@ use core::{ }; use lazy_static::lazy_static; -use uom::{ - fmt::DisplayStyle, - si::{ - angle::{degree, revolution}, - f64::*, - length::foot, - ratio::ratio, - time::second, - velocity::{foot_per_minute, knot}, - }, -}; + +use crate::prelude::*; +use ::uom::fmt::DisplayStyle; +use ::uom::si::ratio::ratio; // ToDo: turn into consts when uom supports const new lazy_static! { @@ -215,12 +208,12 @@ impl AircraftState { self.yaw } */ - pub fn situation(&self) -> Option<&FlightSegment> { - self.situation.as_ref() + pub fn situation(&self) -> &Option { + &self.situation } /// Normalizes the [AircraftState] into a [NormalizedAircraftState] - pub(crate) fn normalize(&self) -> NormalizedAircraftState { + pub fn normalize(&self) -> NormalizedAircraftState { let (lat, lon) = Self::wrap_position(self.position_lat, self.position_lon); NormalizedAircraftState { @@ -309,7 +302,7 @@ impl From for AircraftState { impl Display for AircraftState { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let s = Time::format_args(second, DisplayStyle::Abbreviation); + let s = Time::format_args(time_second, DisplayStyle::Abbreviation); let ft = Length::format_args(foot, DisplayStyle::Abbreviation); let deg = Angle::format_args(degree, DisplayStyle::Abbreviation); let fpm = Velocity::format_args(foot_per_minute, DisplayStyle::Abbreviation); @@ -343,7 +336,7 @@ AircrafState: {{ } /// Represents a flight segment -#[derive(Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] pub enum FlightSegment { /// The aircraft is in cruise flight situation diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 4ed9083..0293ca7 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,39 +1,7 @@ -pub mod ffac; -pub mod mode1; -pub mod mode3; -pub mod pda; +use crate::prelude::*; -use crate::{TawsAlert, TawsAlerts}; -use enum_map::{Enum, EnumMap}; - -/// Alert Source (TAWS functionallities) -#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)] -pub enum AlertSource { - /// Forward Lookig Terrain Avoidance - Flta, - - /// Five Hundred foot altitude Callout - Ffac, - - /// Premature Descent Alerting - Pda, - - /// Excessive Rate of Descent - Mode1, - - /// Excessive ClosureRate to Terrain - Mode2, - - /// Negative Climb Rate or Altitude Loss after Take-off or Go Around - Mode3, - - /// Flight Near Terrain when Not in Landing Configuration - Mode4, - - /// Excessive Downward Deviation from an ILS Glideslope or LPV/GLS Glidepath - Mode5, - // TODO add more -} +pub use hash32::{Hash, Hasher}; +use heapless::FnvIndexMap; /// TAWS Alert levels #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -53,7 +21,7 @@ pub enum AlertLevel { /// Represents a TAWS alert #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub struct Alert { +pub struct Alert { /// The source resp. the TAWS functionallity which emitted this alert pub source: AlertSource, @@ -61,13 +29,19 @@ pub struct Alert { pub level: AlertLevel, } -impl Alert { - pub fn new(source: AlertSource, level: AlertLevel) -> Self { +impl Alert { + /// Creates a new alert with the specified source and level. + /// # Arguments + /// `source` - The source of the alert. + /// `level` - The level of the alert. + pub const fn new(source: AlertSource, level: AlertLevel) -> Self { Alert { source, level } } } -impl TawsAlert for Alert { +impl TawsAlert for Alert { + type AlertSource = AlertSource; + fn source(&self) -> AlertSource { self.source } @@ -77,184 +51,188 @@ impl TawsAlert for Alert { } } -impl From<(AlertSource, AlertLevel)> for Alert { +impl From<(AlertSource, AlertLevel)> for Alert { fn from(alert: (AlertSource, AlertLevel)) -> Self { Self::new(alert.0, alert.1) } } -impl From for (AlertSource, AlertLevel) { - fn from(alert: Alert) -> Self { +impl From> for (AlertSource, AlertLevel) { + fn from(alert: Alert) -> Self { (alert.source, alert.level) } } -/// Represents a set of [Alerts](Alert) -#[derive(Default, Debug)] -pub struct Alerts { - alerts: EnumMap>, +/// Represents a set of [Alerts](Alert) by their [AlertSource](Alert::AlertSource) +#[derive(Debug)] +pub struct Alerts +where + Alert::AlertSource: Hash, +{ + alerts: FnvIndexMap< + Alert::AlertSource, + Alert, + 64, /*ToDo: use ::NUM_ALERT_SOURCES or count the available alert sources with a macro*/ + >, } -impl Alerts { - /// Inserts the specified alert into the set. - /// Already existing alerts are replaced if the [new_alert] has a higher alert level. - /// # Arguments - /// * `new_alert` - the new alert which is added to the set of alerts - /// - /// # Examples - /// ``` - /// - /// use opentaws::{*, alerts::*}; - /// let mut alerts = Alerts::default(); - /// alerts.insert((AlertSource::Mode1, AlertLevel::Caution).into()); - /// assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Annunciation)); - /// assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Caution)); - /// - /// ``` - pub fn insert(&mut self, new_alert: Alert) { - let current_alert = &self.alerts[new_alert.source]; - - if current_alert - .as_ref() - .map_or(true, |alert| new_alert.level < alert.level) - { - self.alerts[new_alert.source].replace(new_alert); +impl Default for Alerts +where + Alert::AlertSource: Hash, +{ + fn default() -> Self { + Self { + alerts: Default::default(), } } } -impl TawsAlerts for Alerts { +impl Alerts +where + Alert::AlertSource: Hash, +{ + /// Returns an iterator over all active alerts. + pub fn alerts(&self) -> impl Iterator + '_ { + self.alerts.values() + } +} + +impl TawsAlerts for Alerts +where + Alert::AlertSource: Hash, +{ type Alert = Alert; + type AlertSource = Alert::AlertSource; - fn is_alert_active(&self, alert_src: AlertSource, min_level: AlertLevel) -> bool { - let current_alert = &self.alerts[alert_src]; + fn insert(&mut self, new_alert: Alert) { + let current_alert = self.alerts.get(&new_alert.source()); - match current_alert { - Some(alert) => alert.level <= min_level, - None => false, + if current_alert.map_or(true, |alert| new_alert.level() < alert.level()) { + self.alerts + .insert(new_alert.source(), new_alert) + .map_err(|_| ()) + .unwrap(); //ToDo } } -} -impl<'a> IntoIterator for &'a Alerts { - type Item = &'a Alert; - type IntoIter = AlertsIter<'a>; + fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool { + self.alerts.contains_key(&alert_src); - fn into_iter(self) -> Self::IntoIter { - AlertsIter { - alerts: self.alerts.as_slice(), - index: 0, + match self.alerts.get(&alert_src) { + Some(alert) => alert.level() <= min_level, + None => false, } } } -/// Represents an iterator over all possible [Alerts](Alert) from all [AlertSources](AlertSource). -pub struct AlertsIter<'a> { - alerts: &'a [Option], - index: usize, -} +#[cfg(test)] +mod tests { + use core::slice::Iter; -impl<'a> Iterator for AlertsIter<'a> { - type Item = &'a Alert; + use super::*; + use hash32::{Hash, Hasher}; + + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + enum TestClass { + A, + B, + C, + } - fn next(&mut self) -> Option { - loop { - if self.index >= self.alerts.len() { - return None; - } + impl TawsAlertSource for TestClass { + const NUM_ALERT_SOURCES: usize = 3; + const ALERT_SOURCES: &'static [Self] = &[]; + } - let alert = &self.alerts[self.index]; - self.index += 1; + impl IntoIterator for TestClass { + type Item = &'static TestClass; - if alert.is_none() { - continue; - } + type IntoIter = Iter<'static, TestClass>; - return alert.as_ref(); + fn into_iter(self) -> Self::IntoIter { + [Self::A, Self::B, Self::C].iter() } } -} - -mod tests { - #![allow(unused_imports)] //ToDo: just to satisfy clippy - use super::*; - - #[test] - fn alert_source_equality() { - let a = AlertSource::Mode1; - let b = AlertSource::Mode1; - let c = AlertSource::Mode2; - assert!(a == b); - assert!(a != c); + impl Hash for TestClass { + fn hash(&self, state: &mut H) + where + H: Hasher, + { + state.write(&(*self as usize).to_le_bytes()); + } } + type TestAlert = Alert; + type TestAlerts = Alerts; + #[test] - fn alert_level_ord() { + fn alert_level_eq() { + assert!(AlertLevel::Warning == AlertLevel::Warning); + assert!(AlertLevel::Warning != AlertLevel::Caution); assert!(AlertLevel::Warning < AlertLevel::Caution); assert!(AlertLevel::Caution < AlertLevel::Annunciation); } #[test] - fn alert_from_tuple() { - let alert: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); - assert!(alert.source == AlertSource::Mode1); - assert!(alert.level == AlertLevel::Warning); - } + fn alert_eq() { + let alert1: TestAlert = (TestClass::A, AlertLevel::Warning).into(); + let alert2: TestAlert = (TestClass::A, AlertLevel::Warning).into(); + let alert3: TestAlert = (TestClass::B, AlertLevel::Warning).into(); + let alert4: TestAlert = (TestClass::A, AlertLevel::Annunciation).into(); - #[test] - fn alert_to_tuple() { - let alert_tuple = (AlertSource::Mode1, AlertLevel::Warning); - let alert: Alert = alert_tuple.into(); - assert!(>::into(alert) == alert_tuple); + assert!(alert1 == alert1); + assert!(alert1 == alert2); + assert!(alert1 != alert3); + assert!(alert1 != alert4); } #[test] - fn alert_source() { - let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); - assert!(a.source() == AlertSource::Mode1); - } + fn alerts_insert() { + let mut alerts = TestAlerts::default(); + assert!(!alerts.alerts.contains_key(&TestClass::A)); - #[test] - fn alert_level() { - let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); - assert!(a.level() == AlertLevel::Warning); - } + let alert1: TestAlert = (TestClass::A, AlertLevel::Warning).into(); + let alert2: TestAlert = (TestClass::A, AlertLevel::Caution).into(); - #[test] - fn alert_eq() { - let a: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); - let b: Alert = (AlertSource::Mode1, AlertLevel::Warning).into(); - let c: Alert = (AlertSource::Mode3, AlertLevel::Warning).into(); - let d: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); - - assert!(a == b); - assert!(a != c); - assert!(a != d); - assert!(c != d); - } + alerts.insert(alert1); + assert!(alerts.alerts.contains_key(&TestClass::A)); - #[test] - fn alerts_default() { - let alerts: Alerts = Alerts::default(); - assert!(alerts.alerts[AlertSource::Mode1] == None) + alerts.insert(alert2); + assert!(alerts.alerts.contains_key(&TestClass::A)); } #[test] - fn alerts_insert() { - let mut alerts: Alerts = Alerts::default(); - let alert: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); - alerts.insert(alert); - assert!(alerts.alerts[AlertSource::Mode1] == Some(alert)); + fn alerts_is_active() { + let mut alerts = TestAlerts::default(); + let alert1: TestAlert = (TestClass::A, AlertLevel::Caution).into(); + + alerts.insert(alert1); + + assert!(alerts.is_alert_active(TestClass::A, AlertLevel::Annunciation)); + assert!(alerts.is_alert_active(TestClass::A, AlertLevel::Caution)); + assert!(!alerts.is_alert_active(TestClass::A, AlertLevel::Warning)); + + let alert2: TestAlert = (TestClass::A, AlertLevel::Annunciation).into(); + alerts.insert(alert2); + assert!(alerts.is_alert_active(TestClass::A, AlertLevel::Caution)); + + let alert3: TestAlert = (TestClass::A, AlertLevel::Warning).into(); + alerts.insert(alert3); + assert!(alerts.is_alert_active(TestClass::A, AlertLevel::Warning)); } #[test] - fn alerts_is_active() { - let mut alerts: Alerts = Alerts::default(); - let alert: Alert = (AlertSource::Mode1, AlertLevel::Caution).into(); - alerts.insert(alert); - assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Annunciation)); - assert!(alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Caution)); - assert!(!alerts.is_alert_active(AlertSource::Mode1, AlertLevel::Warning)); + fn alerts_get() { + let mut alerts = TestAlerts::default(); + let alert1: TestAlert = (TestClass::A, AlertLevel::Annunciation).into(); + let alert2: TestAlert = (TestClass::B, AlertLevel::Caution).into(); + let alert3: TestAlert = (TestClass::C, AlertLevel::Warning).into(); + + alerts.insert(alert1); + alerts.insert(alert2); + alerts.insert(alert3); + + assert!(alerts.alerts().count() == 3) } } diff --git a/opentaws/src/alerts/ffac.rs b/opentaws/src/alerts/ffac.rs deleted file mode 100644 index 739817d..0000000 --- a/opentaws/src/alerts/ffac.rs +++ /dev/null @@ -1,78 +0,0 @@ -use crate::{aircraft_state::FlightSegment, Alert, AlertLevel, AlertSource, TawsFunctionality}; - -use uom::{ - num_traits::Zero, - si::{f64::Length, length::foot}, -}; - -pub struct Ffac { - alert_src: AlertSource, - armed: bool, - inhibited: bool, - - last_altitude: Length, -} - -impl Default for Ffac { - fn default() -> Self { - Self { - alert_src: AlertSource::Ffac, - armed: true, - inhibited: false, - last_altitude: Length::zero(), - } - } -} - -impl TawsFunctionality for Ffac { - type Alert = Alert; - - fn alert_source(&self) -> AlertSource { - self.alert_src - } - - fn is_armed(&self) -> bool { - self.armed - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn process( - &mut self, - state: crate::NormalizedAircraftState, - ) -> Result, ()> { - let armed = state - .situation() - .map(|s| !matches!(s, FlightSegment::TakeOff | FlightSegment::GoAround)) - .ok_or(())?; - - self.armed = armed; - if !self.armed { - return Ok(None); - } - - let fivehundred = Length::new::(500.0); - let result: Result, ()> = - if self.last_altitude >= fivehundred && state.altitude_ground() < fivehundred { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Annunciation))) - } else { - Ok(None) - }; - - if !self.inhibited { - result - } else { - Ok(None) - } - } -} diff --git a/opentaws/src/alerts/mode1.rs b/opentaws/src/alerts/mode1.rs deleted file mode 100644 index 093e7ce..0000000 --- a/opentaws/src/alerts/mode1.rs +++ /dev/null @@ -1,122 +0,0 @@ -use crate::{ - aircraft_state::FlightSegment, - envelope::{Envelope, INVALID_ENVELOPE}, - Alert, AlertLevel, AlertSource, TawsFunctionality, -}; -use lazy_static::lazy_static; -use nalgebra::Vector2; -use uom::si::{length::foot, velocity::foot_per_minute}; - -#[derive(Clone, Debug)] -pub struct Mode1 { - alert_src: AlertSource, - armed: bool, - inhibited: bool, -} - -impl Default for Mode1 { - fn default() -> Self { - Self { - alert_src: AlertSource::Mode1, - armed: true, - inhibited: false, - } - } -} - -impl TawsFunctionality for Mode1 { - type Alert = Alert; - - fn alert_source(&self) -> AlertSource { - self.alert_src - } - - fn is_armed(&self) -> bool { - self.armed - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn process( - &mut self, - state: crate::NormalizedAircraftState, - ) -> Result, ()> { - let altitude = state.altitude_ground().get::(); - let rod = -state.climb_rate().get::(); - let steep_approach = state - .situation() - .map(|s| match s { - FlightSegment::Landing { steep_approach, .. } => *steep_approach, - _ => false, - }) - .ok_or(())?; - - let result = match steep_approach { - true if STEEP_WARNING_ENVELOPE.contains(rod, altitude)? => { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Warning))) - } - true if STEEP_CAUTION_ENVELOPE.contains(rod, altitude)? => { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) - } - false if WARNING_ENVELOPE.contains(rod, altitude)? => { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Warning))) - } - false if CAUTION_ENVELOPE.contains(rod, altitude)? => { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) - } - _ => Err(()), - }; - - if !self.inhibited { - result - } else { - Ok(None) - } - } -} - -lazy_static! { - static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::try_new([ - Vector2::new(100_000.0, 100.0), - Vector2::new(1560.0, 100.0), - Vector2::new(2200.0, 630.0), - Vector2::new(5700.0, 2200.0), - Vector2::new(100_000.0, 2200.0) - ]) - .expect(INVALID_ENVELOPE); - static ref STEEP_CAUTION_ENVELOPE: Envelope<6> = Envelope::try_new([ - Vector2::new(100_000.0, 150.0), - Vector2::new(1798.0, 150.0), - Vector2::new(1944.0, 300.0), - Vector2::new(3233.0, 1078.0), - Vector2::new(6225.0, 2075.0), - Vector2::new(100_000.0, 2075.0) - ]) - .expect(INVALID_ENVELOPE); - static ref WARNING_ENVELOPE: Envelope<5> = Envelope::try_new([ - Vector2::new(100_000.0, 100.0), - Vector2::new(1600.0, 100.0), - Vector2::new(1850.0, 300.0), - Vector2::new(10100.0, 1958.0), - Vector2::new(100_000.0, 1958.0) - ]) - .expect(INVALID_ENVELOPE); - static ref STEEP_WARNING_ENVELOPE: Envelope<5> = Envelope::try_new([ - Vector2::new(100_000.0, 150.0), - Vector2::new(1908.0, 150.0), - Vector2::new(2050.0, 300.0), - Vector2::new(10300.0, 1958.0), - Vector2::new(100_000.0, 1958.0) - ]) - .expect(INVALID_ENVELOPE); -} diff --git a/opentaws/src/alerts/mode3.rs b/opentaws/src/alerts/mode3.rs deleted file mode 100644 index d5d5578..0000000 --- a/opentaws/src/alerts/mode3.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::{ - aircraft_state::FlightSegment, - envelope::{Envelope, INVALID_ENVELOPE}, - Alert, AlertLevel, AlertSource, TawsFunctionality, -}; -use lazy_static::lazy_static; -use nalgebra::Vector2; -use uom::{ - num_traits::Zero, - si::{f64::Length, length::foot, velocity::foot_per_minute}, -}; - -pub struct Mode3 { - alert_src: AlertSource, - armed: bool, - inhibited: bool, - - max_altitude_ground: Length, -} - -impl Default for Mode3 { - fn default() -> Self { - Self { - alert_src: AlertSource::Mode3, - armed: false, - inhibited: false, - - max_altitude_ground: Length::zero(), - } - } -} - -impl TawsFunctionality for Mode3 { - type Alert = Alert; - - fn alert_source(&self) -> AlertSource { - self.alert_src - } - - fn is_armed(&self) -> bool { - self.armed - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn process( - &mut self, - state: crate::NormalizedAircraftState, - ) -> Result, ()> { - let armed = state - .situation() - .map(|s| matches!(s, FlightSegment::TakeOff | FlightSegment::GoAround)) - .ok_or(())?; - - if let (false, true) = (self.armed, armed) { - self.max_altitude_ground = state.altitude_ground() - } - - self.armed = armed; - if !self.armed { - return Ok(None); - } - - self.max_altitude_ground = Length::max(self.max_altitude_ground, state.altitude_ground()); - - let alt_loss = (self.max_altitude_ground - state.altitude_ground()).get::(); - let altitude = state.altitude_ground().get::(); - let rod = -state.climb_rate().get::(); - - let result = if METHODE_1_CAUTION_ENVELOPE.contains(rod, altitude)? - || METHODE_2_CAUTION_ENVELOPE.contains(alt_loss, altitude)? - { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) - } else { - Ok(None) - }; - - if !self.inhibited { - result - } else { - Ok(None) - } - } -} - -lazy_static! { - static ref METHODE_1_CAUTION_ENVELOPE: Envelope::<4> = Envelope::try_new([ - Vector2::new(100_000.0, 60.0), - Vector2::new(207.0, 60.0), - Vector2::new(533.0, 600.0), - Vector2::new(100_000.0, 600.0) - ]) - .expect(INVALID_ENVELOPE); - static ref METHODE_2_CAUTION_ENVELOPE: Envelope::<4> = Envelope::try_new([ - Vector2::new(100_000.0, 60.0), - Vector2::new(26.0, 60.0), - Vector2::new(80.0, 600.0), - Vector2::new(100_000.0, 600.0) - ]) - .expect(INVALID_ENVELOPE); -} diff --git a/opentaws/src/alerts/pda.rs b/opentaws/src/alerts/pda.rs deleted file mode 100644 index 775e495..0000000 --- a/opentaws/src/alerts/pda.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::{ - envelope::{Envelope, INVALID_ENVELOPE}, - Alert, AlertLevel, AlertSource, TawsFunctionality, -}; -use lazy_static::lazy_static; -use nalgebra::Vector2; -use uom::si::length::foot; - -pub struct PDA { - alert_src: AlertSource, - armed: bool, - inhibited: bool, -} - -impl Default for PDA { - fn default() -> Self { - Self { - alert_src: AlertSource::Pda, - armed: false, - inhibited: false, - } - } -} - -impl TawsFunctionality for PDA { - type Alert = Alert; - - fn alert_source(&self) -> AlertSource { - self.alert_src - } - - fn is_armed(&self) -> bool { - self.armed - } - - fn inhibit(&mut self) { - self.inhibited = true; - } - - fn uninhibit(&mut self) { - self.inhibited = false; - } - - fn is_inhibited(&self) -> bool { - self.inhibited - } - - fn process( - &mut self, - state: crate::NormalizedAircraftState, - ) -> Result, ()> { - // ToDo - let altitude_gnd_foot = state.altitude_ground().get::(); - let distance_to_nearest_airport_nm = 3.0; - - self.armed = distance_to_nearest_airport_nm <= 5.0; - if !self.armed { - return Ok(None); - } - - let result: Result, ()> = - if CAUTION_ENVELOPE.contains(distance_to_nearest_airport_nm, altitude_gnd_foot)? { - Ok(Some(Alert::new(self.alert_src, AlertLevel::Caution))) - } else { - Ok(None) - }; - - if !self.inhibited { - result - } else { - Ok(None) - } - } -} - -lazy_static! { - static ref CAUTION_ENVELOPE: Envelope::<6> = Envelope::try_new([ - Vector2::new(5.0, 10.0), - Vector2::new(1.0, 10.0), - Vector2::new(1.0, 80.0), - Vector2::new(1.8, 150.0), - Vector2::new(2.3, 170.0), - Vector2::new(5.0, 170.0) - ]) - .expect(INVALID_ENVELOPE); -} diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs new file mode 100644 index 0000000..438f4dc --- /dev/null +++ b/opentaws/src/class_c.rs @@ -0,0 +1,146 @@ +mod ffac; +//mod flta; +mod mode1; +mod mode3; +mod pda; + +use core::{fmt::Display, slice::Iter}; +use hash32::{Hash, Hasher}; + +use crate::alerts::Alert; +use crate::prelude::*; + +pub use {ffac::*, /*flta::*,*/ mode1::*, mode3::*, pda::*}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub enum ClassC_Source { + Ffac, + //Flta, + Mode1, + Mode3, + Pda, +} + +impl Display for ClassC_Source { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + ClassC_Source::Ffac => f.write_fmt(format_args!("Ffac")), + //SourceClassC::Flta => f.write_fmt(format_args!("Flta")), + ClassC_Source::Mode1 => f.write_fmt(format_args!("Mode1")), + ClassC_Source::Mode3 => f.write_fmt(format_args!("Mode3")), + ClassC_Source::Pda => f.write_fmt(format_args!("Pda")), + } + } +} + +impl TawsAlertSource for ClassC_Source { + const NUM_ALERT_SOURCES: usize = 5; + const ALERT_SOURCES: &'static [Self] = &[ + ClassC_Source::Ffac, + //ClassC_Source::Flta, + ClassC_Source::Mode1, + ClassC_Source::Mode3, + ClassC_Source::Pda, + ]; +} + +impl IntoIterator for ClassC_Source { + type Item = &'static ClassC_Source; + + type IntoIter = Iter<'static, ClassC_Source>; + + fn into_iter(self) -> Self::IntoIter { + [Self::Ffac, Self::Mode1, Self::Mode3, Self::Pda].iter() + } +} + +impl Hash for ClassC_Source { + fn hash(&self, state: &mut H) + where + H: Hasher, + { + state.write(&(*self as usize).to_le_bytes()) + } +} + +pub struct ClassC { + ffac: Ffac, + //flta: flta::Flta, + mode1: Mode1, + mode3: Mode3, + pda: Pda, +} + +impl ClassC { + pub fn new() -> Self { + ClassC { + ffac: Ffac::default(), + //flta: flta:::Flta::default(), + mode1: Mode1::default(), + mode3: Mode3::default(), + pda: Pda::default(), + } + } +} + +impl TawsFunctionalities for ClassC { + type AlertSource = ClassC_Source; + type Alert = Alert; + + fn functionality( + &self, + alert_src: Self::AlertSource, + ) -> &dyn TawsFunctionality { + match alert_src { + ClassC_Source::Ffac => &self.ffac, + //ClassC_Source::Flta => &self.flta, + ClassC_Source::Mode1 => &self.mode1, + ClassC_Source::Mode3 => &self.mode3, + ClassC_Source::Pda => &self.pda, + } + } + + fn functionality_mut( + &mut self, + alert_src: Self::AlertSource, + ) -> &mut dyn TawsFunctionality { + match alert_src { + ClassC_Source::Ffac => &mut self.ffac, + //ClassC_Source::Flta => &mut self.flta, + ClassC_Source::Mode1 => &mut self.mode1, + ClassC_Source::Mode3 => &mut self.mode3, + ClassC_Source::Pda => &mut self.pda, + } + } +} + +#[derive(Debug)] +pub enum ClassCError { + //AlertSourceNotImplemented, + InvalidAircraftState, +} + +impl Display for ClassCError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + /*ClassCError::AlertSourceNotImplemented => { + f.write_fmt(format_args!("Alert source is not implemented.")) + }*/ + ClassCError::InvalidAircraftState => { + f.write_fmt(format_args!("Invalid aircraft state.",)) + } + } + } +} + +impl TawsError for ClassCError {} + +impl From for &dyn TawsError { + fn from(err: ClassCError) -> Self { + match err { + + ClassCError::InvalidAircraftState => &ClassCError::InvalidAircraftState, + } + } +} diff --git a/opentaws/src/class_c/ffac.rs b/opentaws/src/class_c/ffac.rs new file mode 100644 index 0000000..ec5196d --- /dev/null +++ b/opentaws/src/class_c/ffac.rs @@ -0,0 +1,87 @@ +use crate::{alerts::*, prelude::*}; + +use super::{ClassCError, ClassC_Source}; + +use ::uom::num_traits::Zero; +use lazy_static::lazy_static; + +#[derive(Clone, Debug)] +pub struct Ffac { + armed: bool, + inhibited: bool, + + last_altitude: Length, +} + +impl Default for Ffac { + fn default() -> Self { + Self { + armed: true, + inhibited: false, + last_altitude: Length::zero(), + } + } +} + +impl Ffac { + const ALERT_SOURCE: ClassC_Source = ClassC_Source::Ffac; + const ALERT: ::Alert = + ::Alert::new(Self::ALERT_SOURCE, AlertLevel::Annunciation); +} + +impl TawsFunctionality for Ffac { + type AlertSource = ClassC_Source; + type Alert = Alert; + //const ALERT_SOURCE: ::AlertSource = ClassC_Source::Ffac; + + fn alert_source(&self) -> Self::AlertSource { + Self::ALERT_SOURCE + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result>, &'static dyn TawsError> { + let armed = state + .situation() + .map(|s| !matches!(s, FlightSegment::TakeOff | FlightSegment::GoAround)) + .ok_or(ClassCError::InvalidAircraftState)?; + + self.armed = armed; + if !self.armed { + return Ok(None); + } + + let result = (self.last_altitude >= *FIVE_HUNDRED + && state.altitude_ground() < *FIVE_HUNDRED) + .then_some(Self::ALERT); + + self.last_altitude = state.altitude_ground(); + + if self.inhibited { + return Ok(None); + } + + Ok(result) + } +} + +lazy_static! { + static ref FIVE_HUNDRED: Length = Length::new::(500.0); //ToDo make const +} diff --git a/opentaws/src/class_c/mode1.rs b/opentaws/src/class_c/mode1.rs new file mode 100644 index 0000000..bcb2b2f --- /dev/null +++ b/opentaws/src/class_c/mode1.rs @@ -0,0 +1,151 @@ +use crate::{alerts::*, envelope::*, prelude::*}; + +use super::ClassC_Source; + +use lazy_static::lazy_static; +use nalgebra::{Vector, Vector2}; + +#[derive(Clone, Debug)] +pub struct Mode1 { + armed: bool, + inhibited: bool, +} + +impl Default for Mode1 { + fn default() -> Self { + Self { + armed: true, + inhibited: false, + } + } +} + +impl Mode1 { + const ALERT_SOURCE: ClassC_Source = ClassC_Source::Mode1; + const ALERT_WARNING: ::Alert = + ::Alert::new(Self::ALERT_SOURCE, AlertLevel::Warning); + + const ALERT_CAUTION: ::Alert = + ::Alert::new(Self::ALERT_SOURCE, AlertLevel::Caution); +} + +impl TawsFunctionality for Mode1 { + type AlertSource = ClassC_Source; + type Alert = Alert; + + fn alert_source(&self) -> Self::AlertSource { + Self::ALERT_SOURCE + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result, &'static dyn TawsError> { + let rod = -state.climb_rate().get::(); + let altitude_gnd = state.altitude_ground().get::(); + + if !LIMITS.contains(Vector2::new(rod, altitude_gnd)) { + let _x = 437; + } + + let steep_approach = match state.situation() { + Some(FlightSegment::Landing { steep_approach, .. }) => *steep_approach, + _ => false, //Steep envelopes are more relaxed; assume steep envelope is not selected. + }; + + let result = if steep_approach { + let caution = STEEP_CAUTION_ENVELOPE + .contains(rod, altitude_gnd)? + .then_some(Self::ALERT_CAUTION); + let warning = STEEP_WARNING_ENVELOPE + .contains(rod, altitude_gnd)? + .then_some(Self::ALERT_WARNING); + warning.or(caution) + } else { + let caution = CAUTION_ENVELOPE + .contains(rod, altitude_gnd)? + .then_some(Self::ALERT_CAUTION); + let warning = WARNING_ENVELOPE + .contains(rod, altitude_gnd)? + .then_some(Self::ALERT_WARNING); + warning.or(caution) + }; + + if self.inhibited { + return Ok(None); + } + + Ok(result) + } +} + +lazy_static! { + static ref LIMITS: Rect = Rect::new( + // Min/Max climb/descent rate: Mach 10 = +-675197.0 ft/min + // Max altitude above terrain: 100km = 328084 ft + Vector2::new(-680_000.0, 0.0), + Vector2::new(680_000.0, 330000.0) + ); + + // Envelopes enlarged by d=10, to prevent floating pointing problems. + static ref CAUTION_ENVELOPE: Envelope<5> = Envelope::new( + *LIMITS, + &[ + Vector2::new(680000.000, 90.000), + Vector2::new( 1550.592, 96.610), + Vector2::new( 2194.716, 638.490), + Vector2::new( 5697.907, 2209.779), + Vector2::new(680000.000, 2210.000) + ] + ).unwrap(); + + static ref STEEP_CAUTION_ENVELOPE: Envelope<6> = Envelope::new( + *LIMITS, + &[ + Vector2::new(680000.000, 140.000), + Vector2::new( 1788.787, 146.111), + Vector2::new( 1937.782, 307.832), + Vector2::new( 3228.810, 1087.080), + Vector2::new( 6223.399, 2084.871), + Vector2::new(680000.000, 2085.000) + ] + ).unwrap(); + + static ref WARNING_ENVELOPE: Envelope<5> = Envelope::new( + *LIMITS, + &[ + Vector2::new(680000.000, 90.000), + Vector2::new( 1590.564, 96.690), + Vector2::new( 1845.772, 309.062), + Vector2::new( 10099.010, 1967.951), + Vector2::new(680000.000, 1968.000) + ] + ).unwrap(); + + static ref STEEP_WARNING_ENVELOPE: Envelope<5> = Envelope::new( + *LIMITS, + &[ + Vector2::new(680000.000, 140.000), + Vector2::new( 1898.814, 146.047), + Vector2::new( 2045.157, 308.749), + Vector2::new( 10299.010, 1967.951), + Vector2::new(680000.000, 1968.000) + ] + ).unwrap(); +} diff --git a/opentaws/src/class_c/mode3.rs b/opentaws/src/class_c/mode3.rs new file mode 100644 index 0000000..663f8a9 --- /dev/null +++ b/opentaws/src/class_c/mode3.rs @@ -0,0 +1,131 @@ +use crate::{alerts::*, envelope::*, prelude::*}; + +use super::ClassC_Source; + +use ::uom::num_traits::Zero; +use lazy_static::lazy_static; +use nalgebra::Vector2; + +use super::ClassCError; + +#[derive(Clone, Debug)] +pub struct Mode3 { + armed: bool, + inhibited: bool, + + max_altitude_ground: Length, +} + +impl Default for Mode3 { + fn default() -> Self { + Self { + armed: false, + inhibited: false, + + max_altitude_ground: Length::zero(), + } + } +} + +impl Mode3 { + const ALERT_SOURCE: ClassC_Source = ClassC_Source::Mode3; + const ALERT: ::Alert = + ::Alert::new(Self::ALERT_SOURCE, AlertLevel::Caution); +} + +impl TawsFunctionality for Mode3 { + type AlertSource = ClassC_Source; + type Alert = Alert; + + fn alert_source(&self) -> Self::AlertSource { + Self::ALERT_SOURCE + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result>, &'static dyn TawsError> { + let armed = state + .situation() + .map(|sit| matches!(sit, FlightSegment::TakeOff | FlightSegment::GoAround)) + .ok_or(ClassCError::InvalidAircraftState)?; + + if let (false, true) = (self.armed, armed) { + self.max_altitude_ground = state.altitude_ground() + } + + self.armed = armed; + if !self.armed { + return Ok(None); + } + + self.max_altitude_ground = Length::max(self.max_altitude_ground, state.altitude_ground()); + + let altitude_loss = (self.max_altitude_ground - state.altitude_ground()).get::(); + let rod = -state.climb_rate().get::(); + let altitude_gnd = state.altitude_ground().get::(); + + let method1_res = METHODE_1_CAUTION_ENVELOPE.contains(rod, altitude_gnd)?; + let method2_res = METHODE_2_CAUTION_ENVELOPE.contains(altitude_loss, altitude_gnd)?; + let result = (method1_res || method2_res).then_some(Self::ALERT); + + if self.inhibited { + return Ok(None); + } + + Ok(result) + } +} + +lazy_static! { + static ref METHOD1_LIMITS: Rect = Rect::new( + // Min/Max climb/descent rate: +-Mach 10 = +-675197.0 ft/min + // Max altitude above terrain: 100km = 328084 ft + Vector2::new(-680_000.0, 0.0), + Vector2::new(680_000.0, 330_000.0) + ); + + static ref METHOD2_LIMITS: Rect = Rect::new( + // Min/Max alitude loss: +-100km = +-328084 ft + // Max altitude above terrain: 100km = 328084 ft + Vector2::new(-330_000.0, 0.0), + Vector2::new(330_000.0, 330_000.0) + ); + + // Envelopes enlarged by d=10, to prevent floating pointing problems. + static ref METHODE_1_CAUTION_ENVELOPE: Envelope::<4> = Envelope::new( + *METHOD1_LIMITS, + &[ + Vector2::new(680000.000, 50.000), + Vector2::new( 198.291, 55.085), + Vector2::new( 528.085, 608.709), + Vector2::new(680000.000, 610.000) + ] + ).unwrap(); + + static ref METHODE_2_CAUTION_ENVELOPE: Envelope::<4> = Envelope::new( + *METHOD2_LIMITS, + &[ + Vector2::new(330000.000, 50.000), + Vector2::new( 18.585, 53.290), + Vector2::new( 73.290, 607.415), + Vector2::new(330000.000, 610.000) + ] + ).unwrap(); +} diff --git a/opentaws/src/class_c/offset_envelope.ipynb b/opentaws/src/class_c/offset_envelope.ipynb new file mode 100644 index 0000000..7ff4d02 --- /dev/null +++ b/opentaws/src/class_c/offset_envelope.ipynb @@ -0,0 +1,161 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[680000, 100],\n", + " [ 1560, 100],\n", + " [ 2200, 630],\n", + " [ 5700, 2200],\n", + " [680000, 2200]])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#mode1 caution:\n", + "points = np.array([[680000, 100], [1560, 100], [2200, 630], [5700, 2200], [680000, 2200]])\n", + "\n", + "#mode1 caution steep:\n", + "#points = np.array([[680000, 150], [1798, 150], [1944, 300], [3233, 1078], [6225, 2075], [680000, 2075]])\n", + "\n", + "#mode1 warning:\n", + "#points = np.array([[680000, 100], [1600, 100], [1850, 300], [10100, 1958], [680000, 1958]])\n", + "\n", + "#mode1 warning steep:\n", + "#points = np.array([[680000, 150], [1908, 150], [2050, 300], [10300, 1958], [680000, 1958]])\n", + "\n", + "#mode3 method1:\n", + "#points = np.array([[680000, 60], [207, 60], [533, 600], [680000, 600]])\n", + "\n", + "#mode3 method2:\n", + "#points = np.array([[330000, 60], [26, 60], [80, 600], [330000, 600]])\n", + "\n", + "#pda:\n", + "#points = np.array([[5, 10], [1, 10], [1, 80], [1.8, 150], [2.3, 170], [5, 170]])\n", + "\n", + "points" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0. , -1. ],\n", + " [-0.63781397, 0.77019046],\n", + " [-0.40928044, 0.91240864],\n", + " [ 0. , 1. ]])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def normal(p1, p2):\n", + "\tn = (-(p2[1] - p1[1]), p2[0] - p1[0])\n", + "\treturn n / np.linalg.norm(n)\n", + "\n", + "normals = np.array([ normal(p1, p2) for (p1, p2) in zip(points, points[1:])])\n", + "normals" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "|----x---|---y---|\n", + "(680000.000, 90.000),\n", + "( 1550.592, 96.610),\n", + "( 2194.716, 638.490),\n", + "( 5697.907, 2209.779),\n", + "(680000.000, 2210.000),\n" + ] + } + ], + "source": [ + "d = 10\n", + "dist_points = []\n", + "for i in range(len(points)):\n", + " if i == 0:\n", + " p = points[i] + d * normals[0]\n", + " elif i > 0 and i < len(points)-1:\n", + " n = normals[i-1] + normals[i]\n", + " n = n / np.linalg.norm(n)\n", + " p = points[i] + d * n\n", + " elif i == len(points)-1:\n", + " p = points[i] + d * normals[len(points)-2]\n", + "\n", + " dist_points.append(p)\n", + "\n", + "dist_points = np.asarray(dist_points)\n", + "dist_points\n", + "\n", + "print(\"|----x---|---y---|\")\n", + "for p in dist_points:\n", + " print(f\"({p[0]:10.3f}, {p[1]:10.3f}),\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.11.0 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "268e6c34cdb850135cada27548192fd7b18e94d41da1a388422292a2eaee9ad8" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/opentaws/src/class_c/pda.rs b/opentaws/src/class_c/pda.rs new file mode 100644 index 0000000..5b34e00 --- /dev/null +++ b/opentaws/src/class_c/pda.rs @@ -0,0 +1,87 @@ +use crate::{alerts::*, envelope::*, prelude::*}; + +use super::ClassC_Source; + +use lazy_static::lazy_static; + +#[derive(Clone, Debug, Default)] +pub struct Pda { + armed: bool, + inhibited: bool, +} + +impl Pda { + const ALERT_SOURCE: ClassC_Source = ClassC_Source::Pda; + const ALERT: ::Alert = + ::Alert::new(Self::ALERT_SOURCE, AlertLevel::Caution); +} + +impl TawsFunctionality for Pda { + type AlertSource = ClassC_Source; + type Alert = Alert; + + fn alert_source(&self) -> Self::AlertSource { + Self::ALERT_SOURCE + } + + fn is_armed(&self) -> bool { + self.armed + } + + fn inhibit(&mut self) { + self.inhibited = true; + } + + fn uninhibit(&mut self) { + self.inhibited = false; + } + + fn is_inhibited(&self) -> bool { + self.inhibited + } + + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result>, &'static dyn TawsError> { + let altitude_gnd_foot = state.altitude_ground().get::(); + let distance_to_nearest_airport_nm = 3.0; //ToDo + + self.armed = distance_to_nearest_airport_nm <= 5.0; + if !self.armed { + return Ok(None); + } + + let result = CAUTION_ENVELOPE + .contains(distance_to_nearest_airport_nm, altitude_gnd_foot)? + .then_some(Self::ALERT); + + if self.inhibited { + return Ok(None); + } + + Ok(result) + } +} + +lazy_static! { + static ref LIMITS: Rect = Rect::new( + Vector2::zeros(), + // Max. distance to runway: Great circle distance (0, 0) deg to (0, 180) deg = 10819.33045 nm + // Max altitude: 100km = 328084 ft + Vector2::new(11_000.0, 330_000.0) + ); + + // Envelopes enlarged by d=0.1, to prevent floating pointing problems. + static ref CAUTION_ENVELOPE: Envelope::<6> = Envelope::new( + *LIMITS, + &[ + Vector2::new(5.000, 9.900), + Vector2::new(0.929, 9.929), + Vector2::new(0.900, 80.001), + Vector2::new(1.700, 150.002), + Vector2::new(2.230, 170.072), + Vector2::new(5.000, 170.100) + ] + ).unwrap(); +} diff --git a/opentaws/src/envelope.rs b/opentaws/src/envelope.rs index 1f862bb..f48c2b6 100644 --- a/opentaws/src/envelope.rs +++ b/opentaws/src/envelope.rs @@ -1,147 +1,136 @@ -type Vector2 = nalgebra::Vector2; +use core::fmt::Display; -pub const INVALID_ENVELOPE: &str = "Invalid Envelope!"; +use crate::prelude::*; + +pub type Vector2 = nalgebra::Vector2; + +#[derive(Debug)] +pub enum EnvelopeError { + InvalidPolygon, + InvalidLimits, + PolygonNotWithinLimits, + LimitViolation, +} + +impl Display for EnvelopeError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + EnvelopeError::InvalidPolygon => f.write_fmt(format_args!("Invalid polygon.")), + EnvelopeError::InvalidLimits => { + f.write_fmt(format_args!("Envelope limits must be finite.")) + } + EnvelopeError::PolygonNotWithinLimits => f.write_fmt(format_args!( + "Polygon points must be within envelope limits." + )), + EnvelopeError::LimitViolation => { + f.write_fmt(format_args!("Envelope is not defined for the given point.")) + } + } + } +} + +impl TawsError for EnvelopeError {} + +impl From for &dyn TawsError { + fn from(err: EnvelopeError) -> Self { + match err { + EnvelopeError::InvalidPolygon => &EnvelopeError::InvalidPolygon, + EnvelopeError::InvalidLimits => &EnvelopeError::InvalidLimits, + EnvelopeError::PolygonNotWithinLimits => &EnvelopeError::PolygonNotWithinLimits, + EnvelopeError::LimitViolation => &EnvelopeError::LimitViolation, + } + } +} -/// Represents a TAWS Envelope which defines under what conditions an alert should and should not be emitted. pub struct Envelope { - /*/// Defines the operating limits of this envelope.
- /// For states outside these limits the envelope is not defined. - limits: Rect, */ - /// Defines the conditions under which an alert should or should not be emitted. + limits: Rect, //ToDo: make const generic polygon: Polygon, } -impl Envelope { - /// Creates a new Envelope from the given envelope limits and polygon points. - /// # Arguments - /// * `points` - the polygon points which define the envelope. At least 3 points are nessecary. All points must be finite. - /// ToDO (maybe): Augment the polygon to the envelope limits by adding a new start point and new end points to close the polygon with the envelope limits. - pub fn try_new(/* limits: Rect, */ points: [Vector2; N]) -> Result { - /*if !Self::are_valid_limits(&limits) { - return Err(()); - }*/ - - if !Self::are_points_valid(/* &limits, */ &points) { - return Err(()); +impl<'a, const N: usize> Envelope { + pub fn new(limits: Rect, points: &'a [Vector2; N]) -> Result { + let polygon = Polygon::new(points).map_err(|_| EnvelopeError::InvalidPolygon)?; + + if !Self::are_valid_limits(&limits) { + return Err(EnvelopeError::InvalidLimits); + } + + if !Self::is_polygon_within_limits(&limits, &polygon) { + return Err(EnvelopeError::PolygonNotWithinLimits); } - Ok(Self { - //limits, - polygon: Polygon::try_new(points)?, - }) + Ok(Self { limits, polygon }) } - /* /// checks wether the given limits are sufficent for an envelope. fn are_valid_limits(limits: &Rect) -> bool { limits.min.x.is_finite() && limits.min.y.is_finite() && limits.max.x.is_finite() && limits.max.y.is_finite() - } */ + } - /// checks whether the given polygon points are sufficent for an envelope. - /// the polygon must start and end on the envelope limits. all in-between points must be within the envelope limit. - fn are_points_valid(/* limits: &Rect, */ _points: &[Vector2; N]) -> bool { - if N < 3 { - return false; - } + fn is_polygon_within_limits(limits: &Rect, polygon: &Polygon) -> bool { + polygon.points.iter().all(|point| limits.contains(*point)) + } - /* let first_point = points.first().unwrap(); - let last_point = points.last().unwrap(); - if !limits.is_point_on_boundary(*first_point) || !limits.is_point_on_boundary(*last_point) { - return false; - } + pub fn contains(&self, x: f64, y: f64) -> Result { + let point = Vector2::new(x, y); - let mid_points = &points[1..N - 1]; - if !mid_points.iter().all(|point| limits.contains(*point)) { - return false; - } */ + if !self.limits.contains(point) { + return Err(EnvelopeError::LimitViolation); + } - true + Ok(self.polygon.contains(Vector2::new(x, y))) } +} - /* /// Returns whether the envelope is defined for the specified point. - /// # Arguments - /// * `point` - The point which is tested - /// # Returns - /// * `true` if the given point is within the envelope limits; otherwise `false`. - pub fn is_within_limits(&self, point: Vector2) -> bool { - self.limits.contains(point) - } */ - - /// Determines whether the specified (x, y) state is within the envelope. - /// # Arguments - /// * `x` - The first state component. - /// * `y` - The second state compoenent. - /// # Returns - /// * `Ok(bool)` - Indicates whether the given state is within the envelope. - pub fn contains(&self, x: f64, y: f64) -> Result { - /* if !self.is_within_limits(point) { - return Err(()); - } */ +#[derive(Debug)] +pub enum PolygonError<'a> { + TooFewPoints(usize), + InvalidPoints(&'a [Vector2]), +} - Ok(self.polygon.contains(Vector2::new(x, y))) +impl<'a> Display for PolygonError<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + PolygonError::TooFewPoints(n) => f.write_fmt(format_args!( + "At least two points are needed to form a valid polygon. {n} were given." + )), + PolygonError::InvalidPoints(points) => f.write_fmt(format_args!( + "Polygon points must be finite. Points: {points:?}" + )), + } } } -/// Represents an Polygon. -struct Polygon { - /// Points which define the polygon. - /// the last segement from point[-1] to point[0] is implied. +pub struct Polygon { points: [Vector2; N], } -impl Polygon { - /// tries to create a new polygon from the given points. - /// at least 2 points are nessecary. all points must be finite. - fn try_new(points: [Vector2; N]) -> Result { +impl<'a, const N: usize> Polygon { + pub fn new(points: &'a [Vector2; N]) -> Result { if N < 2 { - return Err(()); + return Err(PolygonError::TooFewPoints(N)); } - if !Self::are_points_valid(&points) { - return Err(()); + if !Self::are_points_valid(points) { + return Err(PolygonError::InvalidPoints(points)); } - Ok(Self { points }) + Ok(Self { points: *points }) } - /// check given points. - fn are_points_valid(points: &[Vector2; N]) -> bool { + fn are_points_valid(points: &[Vector2]) -> bool { points .iter() .all(|point| point.x.is_finite() && point.y.is_finite()) } - /// returns the points of the polygon. - fn points(&self) -> &[Vector2; N] { + pub fn points(&self) -> &[Vector2] { &self.points } - /* /// returns the axis-aligned bounding-box for the polygon. - fn bounding_box(&self) -> Rect { - let mut min = Vector2::new(f64::INFINITY, f64::INFINITY); - let mut max = Vector2::new(f64::NEG_INFINITY, f64::NEG_INFINITY); - - for p in self.points { - if p.x < min.x { - min.x = p.x; - } else if p.x > max.x { - max.x = p.x; - } - - if p.y < min.y { - min.y = p.y; - } else if p.y > max.y { - max.y = p.y; - } - } - - Rect::new(min, max) - } */ - - /// returns an iterator over - fn segments(&self) -> impl Iterator + '_ { + pub fn segments(&self) -> impl Iterator + '_ { (0..N).map(|i| (self.points[i], self.points[(i + 1) % N]).into()) } @@ -187,9 +176,9 @@ impl Polygon { } } -/* /// Represents an axis-aligned rectangle. +/// Represents an axis-aligned rectangle. #[derive(Copy, Clone, Default, Debug, PartialEq)] -struct Rect { +pub struct Rect { /// lower left corner min: Vector2, /// upper right corner @@ -198,68 +187,47 @@ struct Rect { impl Rect { /// Creates a rectanlge from two points. - fn new(p1: Vector2, p2: Vector2) -> Rect { - let min = Vector2::new(f64::min(p1.x, p2.x), f64::min(p1.y, p2.y)); - let max = Vector2::new(f64::max(p1.x, p2.x), f64::max(p1.y, p2.y)); + pub fn new(point1: Vector2, point2: Vector2) -> Rect { + let min = Vector2::new(f64::min(point1.x, point2.x), f64::min(point1.y, point2.y)); + let max = Vector2::new(f64::max(point1.x, point2.x), f64::max(point1.y, point2.y)); Rect { min, max } } /// Returns the four corner points starting from the lower left point going in clockwise direction. - fn points(&self) -> [Vector2; 4] { + pub fn points(&self) -> [Vector2; 4] { let dy = Vector2::new(0.0, self.max.y - self.min.y); [self.min, self.min + dy, self.max, self.max - dy] } /// Iterates over the four sides of the rectangle starting from the left vertical segment in clockwise direction. - fn segments(&self) -> impl Iterator + '_ { + pub fn segments(&self) -> impl Iterator + '_ { let points = self.points(); (0..4).map(move |i| (points[i], points[(i + 1) % 4]).into()) } /// Determines whether the specified point is within or on the reactangle. - fn contains(&self, point: Vector2) -> bool { + pub fn contains(&self, point: Vector2) -> bool { (self.min.x <= point.x && point.x <= self.max.x) && (self.min.y <= point.y && point.y <= self.max.y) } +} - /// Determines whether the specified point is on the rectangle boundary. - fn is_point_on_boundary(&self, point: Vector2) -> bool { - if !self.contains(point) { - return false; - } - - point.x == self.min.x - || point.x == self.max.y - || point.y == self.min.y - || point.y == self.max.y - } -} */ - -/// Represents a line segment. #[derive(Copy, Clone, Default, Debug, PartialEq)] pub struct LineSegment { - /// First point which defines the line segment. point1: Vector2, - /// Second point which defines the line segment. point2: Vector2, } impl LineSegment { - /// Create a new line segment. - pub fn new(p1: Vector2, p2: Vector2) -> Self { - Self { - point1: p1, - point2: p2, - } + pub fn new(point1: Vector2, point2: Vector2) -> Self { + Self { point1, point2 } } - /// Returns the mid point of the line segment. pub fn mid(&self) -> Vector2 { self.point1 + 0.5 * (self.point2 - self.point1) } - /// Determines whether the specified point is on the line segment. pub fn contains(&self, point: Vector2) -> bool { let ab = self.point2 - self.point1; let ac = point - self.point1; @@ -290,7 +258,6 @@ impl LineSegment { true } - /// Translates the line segment by the specified offset. pub fn translate(&self, offset: Vector2) -> LineSegment { (self.point1 + offset, self.point2 + offset).into() } @@ -314,6 +281,18 @@ mod tests { use super::*; + #[test] + fn test_segment_mid() { + let l: LineSegment = (Vector2::zeros(), Vector2::zeros()).into(); + assert!(l.mid() == Vector2::zeros()); + + let l: LineSegment = (Vector2::new(100.0, 100.0), Vector2::new(100.0, 100.0)).into(); + assert!(l.mid() == Vector2::new(100.0, 100.0)); + + let l: LineSegment = (Vector2::zeros(), Vector2::new(100.0, 100.0)).into(); + assert!(l.mid() == Vector2::new(50.0, 50.0)); + } + #[test] fn test_segment_contains() { let l: LineSegment = (Vector2::zeros(), Vector2::new(100.0, 100.0)).into(); @@ -327,6 +306,105 @@ mod tests { assert!(!l.contains(Vector2::zeros())) } + #[test] + fn test_segment_translate() { + let l: LineSegment = (Vector2::zeros(), Vector2::zeros()).into(); + let l = l.translate(Vector2::new(100.0, -100.0)); + assert!(l.point1 == Vector2::new(100.0, -100.0) && l.point2 == Vector2::new(100.0, -100.0)); + + let l: LineSegment = (Vector2::zeros(), Vector2::new(100.0, 100.0)).into(); + let l = l.translate(Vector2::new(100.0, -100.0)); + assert!(l.point1 == Vector2::new(100.0, -100.0) && l.point2 == Vector2::new(200.0, 0.0)); + } + + #[test] + fn test_rect_points() { + let r = Rect::new(Vector2::zeros(), Vector2::zeros()); + assert!(r.points().iter().all(|&p| p == Vector2::zeros())); + + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + assert!(r.points().iter().enumerate().all(|(i, &p)| match i { + 0 => p == Vector2::zeros(), + 1 => p == Vector2::new(0.0, 100.0), + 2 => p == Vector2::new(100.0, 100.0), + 3 => p == Vector2::new(100.0, 0.0), + _ => false, + })); + } + + #[test] + fn test_rect_segments() { + let r = Rect::new(Vector2::zeros(), Vector2::zeros()); + assert!(r + .segments() + .all(|seg| seg == LineSegment::new(Vector2::zeros(), Vector2::zeros()))); + + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + assert!(r.segments().enumerate().all(|(i, seg)| match i { + 0 => seg == LineSegment::new(Vector2::zeros(), Vector2::new(0.0, 100.0)), + 1 => seg == LineSegment::new(Vector2::new(0.0, 100.0), Vector2::new(100.0, 100.0)), + 2 => seg == LineSegment::new(Vector2::new(100.0, 100.0), Vector2::new(100.0, 0.0)), + 3 => seg == LineSegment::new(Vector2::new(100.0, 0.0), Vector2::new(0.0, 0.0)), + _ => false, + })); + } + + #[test] + fn test_rect_contains() { + let r = Rect::new(Vector2::zeros(), Vector2::zeros()); + assert!(r.contains(Vector2::zeros())); + assert!(!r.contains(Vector2::new(1.0, 1.0))); + + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + assert!(r.points().iter().all(|&p| r.contains(p))); + assert!(r.contains(Vector2::new(50.0, 50.0))); + assert!(!r.contains(Vector2::new(101.0, 101.0))); + } + + #[test] + fn test_polygon_new() { + assert!(matches!( + Polygon::new(&[Vector2::zeros()]), + Err(PolygonError::TooFewPoints(1)) + )); + + assert!(matches!( + Polygon::new(&[ + Vector2::new(100.0, 100.0), + Vector2::new(f64::INFINITY, 150.0), + ]), + Err(PolygonError::InvalidPoints(_)) + )); + + assert!(matches!( + Polygon::new(&[Vector2::new(100.0, 100.0), Vector2::new(f64::NAN, 150.0),]), + Err(PolygonError::InvalidPoints(_)) + )) + } + + #[test] + fn test_polygon_points() { + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let p = Polygon::new(&r.points()).unwrap(); + + assert!(p + .points() + .iter() + .zip(r.points().iter()) + .all(|(p1, p2)| p1 == p2)) + } + + #[test] + fn test_polygon_segments() { + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let p = Polygon::new(&r.points()).unwrap(); + + assert!(p + .segments() + .zip(r.segments()) + .all(|(seg1, seg2)| seg1 == seg2)) + } + #[test] fn test_polygon_contains() { let points = [ @@ -335,7 +413,7 @@ mod tests { Vector2::new(100.0, 100.0), Vector2::new(100.0, 0.0), ]; - let poly = Polygon::try_new(points).unwrap(); + let poly = Polygon::new(&points).unwrap(); assert!(points.iter().all(|point| poly.contains(*point))); assert!(poly @@ -357,7 +435,7 @@ mod tests { Vector2::new(300.0, 200.0), Vector2::new(300.0, 100.0), ]; - let poly = Polygon::try_new(points).unwrap(); + let poly = Polygon::new(&points).unwrap(); assert!(points.iter().all(|point| poly.contains(*point))); assert!(poly @@ -375,7 +453,7 @@ mod tests { Vector2::new(10.0, 10.0), ]; - let poly = Polygon::try_new(points).unwrap(); + let poly = Polygon::new(&points).unwrap(); assert!(points.iter().all(|point| poly.contains(*point))); assert!(poly .segments() @@ -387,29 +465,84 @@ mod tests { } #[test] - fn test_envelope() { - /* let limits = Rect { - min: Vector2::zeros(), - max: Vector2::new(100.0, 100.0), - }; */ - - let points = [ - Vector2::new(10.0, 0.0), - Vector2::new(10.0, 75.0), - Vector2::new(100.0, 75.0), + fn test_envelope_new() { + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let p = [Vector2::zeros()]; + let e = Envelope::new(r, &p); + assert!(matches!(e, Err(EnvelopeError::InvalidPolygon))); + + let r = Rect::new(Vector2::zeros(), Vector2::new(f64::INFINITY, 100.0)); + let p = [ + Vector2::zeros(), + Vector2::new(0.0, 100.0), + Vector2::new(100.0, 100.0), + Vector2::new(0.0, 100.0), ]; + let e = Envelope::new(r, &p); + assert!(matches!(e, Err(EnvelopeError::InvalidLimits))); - let envelope = Envelope::try_new(/* limits, */ points).unwrap(); + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let p = [ + Vector2::zeros(), + Vector2::new(0.0, 100.0), + Vector2::new(101.0, 101.0), + Vector2::new(0.0, 100.0), + ]; + let e = Envelope::new(r, &p); + assert!(matches!(e, Err(EnvelopeError::PolygonNotWithinLimits))); - /* assert!(envelope.is_within_limits(Vector2::zeros())); - assert!(envelope.is_within_limits(Vector2::new(100.0, 100.0))); - assert!(envelope.is_within_limits(Vector2::new(0.0, 100.0))); - assert!(envelope.is_within_limits(Vector2::new(100.0, 0.0))); - assert!(!envelope.is_within_limits(Vector2::new(150.0, 150.0))); */ + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let p = [ + Vector2::zeros(), + Vector2::new(100.0, 0.0), + Vector2::new(100.0, 100.0), + ]; + let e = Envelope::new(r, &p); + assert!(matches!(e, Ok(_))); + } - assert!(!envelope.contains(0.0, 0.0).unwrap()); - assert!(!envelope.contains(100.0, 100.0).unwrap()); - assert!(envelope.contains(50.0, 50.0).unwrap()); - assert!(envelope.contains(150.0, 150.0) == Err(())); + #[test] + fn test_envelope_contains() { + let r = Rect::new(Vector2::zeros(), Vector2::new(100.0, 100.0)); + let e = Envelope::new( + r, + &[ + Vector2::new(100.0, 100.0), + Vector2::new(100.0, 0.0), + Vector2::new(0.0, 0.0), + ], + ) + .unwrap(); + + assert!(matches!(e.contains(0.0, 0.0), Ok(true))); + assert!(matches!(e.contains(100.0, 0.0), Ok(true))); + assert!(matches!(e.contains(100.0, 100.0), Ok(true))); + assert!(matches!(e.contains(50.0, 50.0), Ok(true))); + assert!(matches!(e.contains(50.0, 50.0), Ok(true))); + assert!(matches!(e.contains(75.0, 50.0), Ok(true))); + + assert!(matches!(e.contains(0.0, 100.0), Ok(false))); + assert!(matches!(e.contains(0.0, 50.0), Ok(false))); + assert!(matches!(e.contains(25.0, 50.0), Ok(false))); + + assert!(matches!( + e.contains(-1.0, 50.0), + Err(EnvelopeError::LimitViolation) + )); + + assert!(matches!( + e.contains(101.0, 50.0), + Err(EnvelopeError::LimitViolation) + )); + + assert!(matches!( + e.contains(50.0, -1.0), + Err(EnvelopeError::LimitViolation) + )); + + assert!(matches!( + e.contains(50.0, 101.0), + Err(EnvelopeError::LimitViolation) + )); } } diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 4d0872f..6220b21 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -8,70 +8,163 @@ //! and C ABI as addiotional targets, but this did not lead anywehre usable _so far_. We are very //! open to suggestions, so please open an issue if you have some feedback. +//#![feature(return_position_impl_trait_in_trait)] #![no_std] #![deny(unsafe_code)] #![allow(dead_code)] -extern crate enum_map; - #[cfg(test)] #[macro_use] extern crate std; -pub mod aircraft_state; +mod aircraft_state; pub mod alerts; -pub(crate) mod envelope; +pub mod class_c; +pub mod envelope; +pub mod prelude; + +use prelude::*; -pub use aircraft_state::{AircraftState, NormalizedAircraftState}; -pub use alerts::{Alert, AlertLevel, AlertSource}; +use core::fmt::Display; /// Abstraction for a TAWS system pub trait Taws { - type Alert: TawsAlert + Sized; - /// Alert set type + /// Alert source type + type AlertSource: TawsAlertSource; + + /// Alert type + type Alert: TawsAlert; + + /// Alert-set type type Alerts: TawsAlerts + Default; - //fn arm(&mut self, alert_src: AlertSource); - //fn disarm(&mut self, alert_src: AlertSource); + type Functionalities: TawsFunctionalities; + + fn functionalities( + &self, + ) -> &dyn TawsFunctionalities; - // ToDo: - //fn functionality(&self) -> Option; - //fn functionalities(&self) -> iterator, array, slice ???; + fn functionalities_mut( + &mut self, + ) -> &mut dyn TawsFunctionalities; /// Returns whether the specified alert source (TAWS functionality) is currently armed. /// # Arguments /// * `alert_src` - The alert source of which the armed state is returned. - fn is_armed(&self, alert_src: AlertSource) -> bool; + fn is_armed(&self, alert_src: Self::AlertSource) -> bool { + self.functionalities().is_armed(alert_src) + } /// Inhibits the output of the specified alert source. /// # Arguements /// * `alert_src` - The alert source to inhibit. - fn inhibit(&mut self, alert_src: AlertSource); + fn inhibit(&mut self, alert_src: Self::AlertSource) { + self.functionalities_mut().inhibit(alert_src) + } /// Un-inhibits the output of the specified alert source. /// # Arguements /// * `alert_src` - The alert source to un-inhibit. - fn uninhibit(&mut self, alert_src: AlertSource); + fn uninhibit(&mut self, alert_src: Self::AlertSource) { + self.functionalities_mut().uninhibit(alert_src) + } /// Returns whether the specified alert source is currently inhibited. /// # Arguments /// * `alert_src` - The alert source of which the inhibit state is returned. - fn is_inhibited(&self, alert_src: AlertSource) -> bool; + fn is_inhibited(&self, alert_src: Self::AlertSource) -> bool { + self.functionalities().is_inhibited(alert_src) + } /// Processes a normalized [AircraftState] and /// returns an alert for each alert source if the related conditions for this TAWS functionality are given. /// # Arguments /// * `state` - The normalized [AircraftState] to process. - fn process(&mut self, state: NormalizedAircraftState) -> Self::Alerts; //ToDo: Result ? + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result { + let mut alerts = Self::Alerts::default(); + let funcs = self.functionalities_mut(); + for alert_src in ::ALERT_SOURCES { + let alert = funcs.functionality_mut(*alert_src).process(state)?; + if let Some(alert) = alert { + alerts.insert(alert); + } + } + + Ok(alerts) + } +} + +pub trait TawsFunctionalities { + type AlertSource: TawsAlertSource; + type Alert: TawsAlert; + + fn functionality( + &self, + alert_src: Self::AlertSource, + ) -> &dyn TawsFunctionality; + + fn functionality_mut( + &mut self, + alert_src: Self::AlertSource, + ) -> &mut dyn TawsFunctionality; + + /// Returns whether the specified alert source (TAWS functionality) is currently armed. + /// # Arguments + /// * `alert_src` - The alert source of which the armed state is returned. + // ToDo: return -> Result when feature(return_position_impl_trait_in_trait) is stable. + fn is_armed(&self, alert_src: Self::AlertSource) -> bool { + self.functionality(alert_src).is_armed() + } + + /// Inhibits the output of the specified alert source. + /// # Arguements + /// * `alert_src` - The alert source to inhibit. + fn inhibit(&mut self, alert_src: Self::AlertSource) { + self.functionality_mut(alert_src).inhibit(); + } + + /// Un-inhibits the output of the specified alert source. + /// # Arguements + /// * `alert_src` - The alert source to un-inhibit. + fn uninhibit(&mut self, alert_src: Self::AlertSource) { + self.functionality_mut(alert_src).uninhibit(); + } + + /// Returns whether the specified alert source is currently inhibited. + /// # Arguments + /// * `alert_src` - The alert source of which the inhibit state is returned. + fn is_inhibited(&self, alert_src: Self::AlertSource) -> bool { + self.functionality(alert_src).is_inhibited() + } + + /// Processes a normalized [AircraftState] and + /// returns an alert for each alert source if the related conditions for this TAWS functionality are given. + /// # Arguments + /// * `alert_src` - The alert source to process. + /// * `state` - The normalized [AircraftState] to process. + fn process( + &mut self, + alert_src: Self::AlertSource, + state: &NormalizedAircraftState, + ) -> Result, &'static dyn TawsError> { + self.functionality_mut(alert_src).process(state) + } } /// Represents a TAWS functionality pub trait TawsFunctionality { + type AlertSource: TawsAlertSource; + /// Alert type - type Alert: TawsAlert; + type Alert: TawsAlert; + + /// The associated alert source of this functionality. + //const ALERT_SOURCE: ::AlertSource; - /// Returns the alert source which is controlled by this functionality. - fn alert_source(&self) -> AlertSource; + fn alert_source(&self) -> Self::AlertSource; /// Returns whether the functionality is armed. fn is_armed(&self) -> bool; @@ -88,26 +181,49 @@ pub trait TawsFunctionality { /// Processes a normalized [AircraftState] and returns an alert result or an error. /// # Arguments /// * `state` - The normalized [AircraftState] to process. - fn process(&mut self, state: NormalizedAircraftState) -> Result, ()>; // Todo Error type? anyhow, thiserror, snafu, ...?; Return multiple alerts? -} - -/// Abstraction for a TAWS alert -pub trait TawsAlert: Into<(AlertSource, AlertLevel)> + Eq { - /// Returns the TAWS functionallity which emitted this alert - fn source(&self) -> AlertSource; - - /// Returns the alert level of this alert - fn level(&self) -> AlertLevel; + fn process( + &mut self, + state: &NormalizedAircraftState, + ) -> Result, &'static dyn TawsError>; // Result ? } /// Abstraction for a set of TAWS alerts pub trait TawsAlerts { + type AlertSource: TawsAlertSource; + /// Alert type - type Alert: TawsAlert; + type Alert: TawsAlert; + + /// Inserts the specified alert into the set. + /// Already existing alerts are replaced if the [new_alert] has a higher alert level. + /// # Arguments + /// * `new_alert` - the new alert which is added to the set of alerts + fn insert(&mut self, new_alert: Self::Alert); /// Returns whether an alert from the given source with at least the specified alert level is active. /// # Arguments - /// * `alert_src` - The alert source (TAWS functionallity) to check for - /// * `min_level` - The inclusive min level to check for - fn is_alert_active(&self, alert_src: AlertSource, min_level: AlertLevel) -> bool; + /// * `alert_src` - The alert source to check for. + /// * `min_level` - The inclusive min level to check for. + fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool; +} + +/// Abstraction for a TAWS alert +pub trait TawsAlert { + /// Alert source + type AlertSource: TawsAlertSource; + + /// Returns the alert source to which this alert belongs. + fn source(&self) -> Self::AlertSource; + + /// Returns the alert level of this alert. + fn level(&self) -> AlertLevel; +} + +/// Abstraction for an alert source +pub trait TawsAlertSource: Clone + Copy + Eq + 'static { + const NUM_ALERT_SOURCES: usize; + + const ALERT_SOURCES: &'static [Self]; } + +pub trait TawsError: core::fmt::Debug + Display {} diff --git a/opentaws/src/prelude.rs b/opentaws/src/prelude.rs new file mode 100644 index 0000000..f6006e9 --- /dev/null +++ b/opentaws/src/prelude.rs @@ -0,0 +1,16 @@ +pub use self::uom::*; +pub use crate::aircraft_state::{AircraftState, FlightSegment, NormalizedAircraftState}; +pub use crate::alerts::AlertLevel; +pub use crate::{ + Taws, TawsAlert, TawsAlertSource, TawsAlerts, TawsError, TawsFunctionalities, TawsFunctionality, +}; + +mod uom { + pub use uom::si::f64::{Angle, Length, Time, Velocity}; + pub use uom::si::{ + angle::{degree, minute as angular_minute, revolution, second as angular_second}, + length::{foot, kilometer, meter, nautical_mile}, + time::second as time_second, + velocity::{foot_per_minute, kilometer_per_hour, knot, meter_per_second}, + }; +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..2f47d05 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable-x86_64-pc-windows-msvc" +#channel = "nightly-x86_64-pc-windows-msvc" diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index b1810f8..25e86dc 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -6,7 +6,7 @@ authors = [ "Janick Beck ", "Umut Durak ", ] -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" description = "A minimal implementation of openTAWS" documentation = "https://aeronautical-informatics.github.io/openTAWS/" @@ -33,18 +33,18 @@ serde = { version = "1.0", default-features = false, features = ["derive"] } # testing and examples arbitrary = { version = "1", features = ["derive"], optional = true } -async-tungstenite = { version = "*", features = [ - "async-std-runtime", -], optional = true } -async-trait = { version = "0.1", optional = true } +#async-tungstenite = { version = "*", features = [ +# "async-std-runtime", +#], optional = true } +#async-trait = { version = "0.1", optional = true } cucumber = { version = "0", optional = true } futures = { version = "0", optional = true } lazy_static = { version = "1.4", optional = true } rand = { version = "*", optional = true } rand_pcg = { version = "*", optional = true } -rayon = { version = "1.5", optional = true } -serde_json = { version = "1.0", optional = true } -smol = { version = "1", optional = true } +#rayon = { version = "1.5", optional = true } +#serde_json = { version = "1.0", optional = true } +#smol = { version = "1", optional = true } regex = "1" @@ -54,17 +54,13 @@ harness = false # Allows Cucumber to print output instead of libtest path = "tests/cucumber.rs" required-features = [ "arbitrary", - "async-trait", + #"async-trait", "cucumber", "futures", "lazy_static", "rand", "rand_pcg", - "rayon", - "serde_json", - "smol", + #"rayon", + #"serde_json", + #"smol", ] - -[[example]] -name = "flightgear" -required-features = ["async-tungstenite", "futures", "serde_json", "smol"] diff --git a/taws_minimal/examples/flightgear.rs b/taws_minimal/examples/flightgear.rs deleted file mode 100644 index 3f49d11..0000000 --- a/taws_minimal/examples/flightgear.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! This demo illustrates how the openTAWS system can be integrated with Flightgear - -use std::{env, error::Error, time::Instant}; - -use futures::prelude::*; - -use async_tungstenite::tungstenite::Message; -use aviation_database::reference::AirportDatabaseImpl; -use serde::{Deserialize, Serialize}; -use uom::si::velocity::foot_per_second; - -use opentaws::prelude::*; -use taws_minimal::MinimalTaws; - -#[derive(Serialize)] -struct FlightgearCommand { - command: String, - node: String, -} - -/// Yields AircraftStates from a Flightgear http/json connection -/// -/// # Arguments -/// `base_uri` - The base URI of the Flightgear http interface. Something like `localhost:5400`. -async fn new_flightgear_stream( - base_uri: &str, -) -> Result>>, Box> { - let url = format!("ws://{}/PropertyListener", base_uri); - let (mut stream, _) = async_tungstenite::async_std::connect_async(url).await?; - - for node in KEYS { - let sub = FlightgearCommand { - command: "addListener".to_string(), - node: node.to_string(), - }; - stream - .send(Message::Binary(serde_json::to_vec(&sub)?)) - .await?; - } - - Ok(stream - .map(|msg| -> Result<_, Box> { Ok(serde_json::from_slice(&msg?.into_data())?) })) -} - -#[derive(Deserialize)] -struct PropertyTreeLeaf { - pub path: String, - pub ts: f64, - pub value: f64, -} - -const KEYS: &'static [&'static str] = &[ - "/velocities/groundspeed-kt", - "/velocities/vertical-speed-fps", - "/position/longitude-deg", - "/position/latitude-deg", - "/position/altitude-ft", - "/position/altitude-agl-ft", - "/orientation/pitch-deg", - "/orientation/roll-deg", - "/orientation/heading-deg", -]; - -const USAGE: &'static str = "usage: "; - -// http://localhost:5400/json/velocities?i=y&t=y&d=3 - -fn main() -> Result<(), Box> { - smol::block_on(async { - let args: Vec = env::args().collect(); - let base_uri = args.get(1).expect(USAGE); - - let airport_database = AirportDatabaseImpl::default(); - let config = TawsConfig { - terrain_server: &airport_database, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - }; - let mut taws = MinimalTaws::new(&config); - let mut fg_stream = new_flightgear_stream(base_uri.as_str()).await?; - let mut frames: u128 = 0; - - let mut aircraft_state = AircraftState::default(); - - loop { - let leaf = fg_stream.next().await.unwrap()?; - let now = Instant::now(); - let ts = Time::new::(leaf.ts); - - // Next frame begins - if ts > aircraft_state.timestamp { - let alert_state = taws.process(&aircraft_state); - print!("{esc}[2J{esc}[1;1H", esc = 27 as char); - frames += 1; - println!( - "Processed frame: {}, time consumed: {:?}", - frames, - now.elapsed(), - ); - println!("{}\n{:#?}", aircraft_state, alert_state); - } - aircraft_state.timestamp = ts; - - match leaf.path.as_str() { - "/velocities/groundspeed-kt" => { - aircraft_state.speed_ground = Velocity::new::(leaf.value) - } - "/velocities/vertical-speed-fps" => { - aircraft_state.climb_rate = Velocity::new::(leaf.value) - } - "/position/longitude-deg" => { - aircraft_state.position_lon = Angle::new::(leaf.value) - } - "/position/latitude-deg" => { - aircraft_state.position_lat = Angle::new::(leaf.value) - } - "/position/altitude-ft" => { - aircraft_state.altitude = Length::new::(leaf.value) - } - "/position/altitude-agl-ft" => { - aircraft_state.altitude_ground = Length::new::(leaf.value) - } - "/orientation/pitch-deg" => aircraft_state.pitch = Angle::new::(leaf.value), - "/orientation/roll-deg" => aircraft_state.roll = Angle::new::(leaf.value), - "/orientation/heading-deg" => { - aircraft_state.heading = Angle::new::(leaf.value) - } - _ => {} - } - } - }) -} diff --git a/taws_minimal/features/alert_prioritization.feature b/taws_minimal/features/alert_prioritization.feature deleted file mode 100644 index ab73fc9..0000000 --- a/taws_minimal/features/alert_prioritization.feature +++ /dev/null @@ -1,18 +0,0 @@ -Feature: Alert Priorization - Class C Equipment shall (TAWS_MOPS_300) include an alert prioritization scheme to - handle concurrent alert conditions. Note: Class C Equipment does not require prioritization with external systems such as - TCAS, RWS, and PWS. In many of the situations that trigger a given alert in the must alert figures above, - multiple alerts may be triggered concurrently. It is acceptable for the TAWS to issue only the highest - priority alert in these situations. For example, an FLTA warning may occur in a Mode 3 - caution must alert region. In this case, Class C Equipment needs to only issue the FLTA - warning response. - - @MOPS_300 - Scenario: Alert Priorization - When concurrent alert conditions trigger - Then the priorization of the alerts handles the concurrency - - @MOPS_300 - Scenario: Alert Priority - Given an alert can occur concurrently - Then that alert has a priority \ No newline at end of file diff --git a/taws_minimal/features/ffac.feature b/taws_minimal/features/ffac.feature index ae5f8a3..79985b8 100644 --- a/taws_minimal/features/ffac.feature +++ b/taws_minimal/features/ffac.feature @@ -36,7 +36,7 @@ Each of these additional categories of callouts is not required. Then FFAC shall be armed @AURAL_ALERT @ANNUNCIATION @MOPS_293 - Scenario: Class C Equipment shall (TAWS_MOPS_293) be capable of providing or triggering a voice callout of “five hundred” ... + Scenario: Class C Equipment shall be capable of providing or triggering a voice callout of “five hundred” ... Given not implemented Rule: Five Hundred Foot Altitude Callout above terrain diff --git a/taws_minimal/features/mode_1.feature b/taws_minimal/features/mode_1.feature index a5b4a78..bc461c5 100644 --- a/taws_minimal/features/mode_1.feature +++ b/taws_minimal/features/mode_1.feature @@ -33,8 +33,8 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @CAUTION @MOPS_270 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. Given Mode 1 is inhibited - When the rate of descent is 1560.0 feet per minute - When the height above terrain is 100.0 feet + When the rate of descent is equal 1560.0 feet per minute + When the height above terrain is equal 100.0 feet Then a Mode 1 caution shall not be emitted @ALERT_CRITERIA @CAUTION @MOPS_270 @@ -79,8 +79,8 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @CAUTION @MOPS_272 Scenario: Class C Equipment shall not provide a Mode 1 caution alert when ... Mode 1 is inhibited. Given Mode 1 is inhibited - When the rate of descent is 1798.0 feet per minute - When the height above terrain 150.0 feet + When the rate of descent is equal 1798.0 feet per minute + When the height above terrain is equal 150.0 feet Then a Mode 1 caution shall not be emitted @ALERT_CRITERIA @CAUTION @MOPS_272 @@ -124,8 +124,8 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @WARNING @MOPS_274 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. Given Mode 1 is inhibited - When the rate of descent is 1600.0 feet per minute - When the height above terrain is 100.0 feet + When the rate of descent is equal 1600.0 feet per minute + When the height above terrain is equal 100.0 feet Then a Mode 1 warning shall not be emitted @ALERT_CRITERIA @WARNING @MOPS_274 @@ -168,8 +168,8 @@ Feature: Excessive Rate of Descent (Mode 1) @ALERT_CRITERIA @WARNING @MOPS_276 Scenario: Class C Equipment shall not provide a Mode 1 warning alert when ... Mode 1 is inhibited. Given Mode 1 is inhibited - When the rate of descent is 1908.0 feet per minute - When the height above terrain is 150.0 feet + When the rate of descent is equal 1908.0 feet per minute + When the height above terrain is equal 150.0 feet Then a Mode 1 warning shall not be emitted @ALERT_CRITERIA @WARNING @MOPS_276 diff --git a/taws_minimal/features/mode_3.feature b/taws_minimal/features/mode_3.feature index e82114e..8a106e7 100644 --- a/taws_minimal/features/mode_3.feature +++ b/taws_minimal/features/mode_3.feature @@ -49,7 +49,7 @@ Feature: Negative Climb Rate or Altitude Loss (Mode 3) Given the aircraft is not on a take-off segment Given Mode 3 is not inhibited When the rate of descent is at least 207.0 feet per minute - When the height above terrain is 60.0 feet + When the height above terrain is equal 60.0 feet Then Mode 3 is not armed Then a Mode 3 caution shall not be emitted @@ -58,7 +58,7 @@ Feature: Negative Climb Rate or Altitude Loss (Mode 3) Given the aircraft is on a take-off segment Given Mode 3 is inhibited When the rate of descent is at least 207.0 feet per minute - When the height above terrain is 60.0 feet + When the height above terrain is equal 60.0 feet Then Mode 3 is armed Then a Mode 3 caution shall not be emitted @@ -83,24 +83,24 @@ Feature: Negative Climb Rate or Altitude Loss (Mode 3) Scenario Outline: Class C Equipment shall provide a caution alert when ... Given the aircraft is on a take-off segment Given Mode 3 is not inhibited - When the height above terrain is between 60.0 feet + When the height above terrain is between 86.0 and feet Given in the next phase - When the height above terrain is at most feet + When the height above terrain is between 60.0 and feet Then Mode 3 is armed Then a Mode 3 caution shall be emitted Examples: | init_max_height_terrain | next_max_height_terrain | - | 60.0 | 34.0 | + | 86.0 | 60.0 | | 600.0 | 520.0 | @ALERT_CRITERIA @CAUTION @MOPS_289 Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is not armed. Given the aircraft is not on a take-off segment Given Mode 3 is not inhibited - When the height above terrain is 60.0 feet + When the height above terrain is equal 60.0 feet Given in the next phase - When the height above terrain is at 34.0 feet + When the height above terrain is equal 34.0 feet Then Mode 3 is not armed Then a Mode 3 caution shall not be emitted @@ -108,9 +108,9 @@ Feature: Negative Climb Rate or Altitude Loss (Mode 3) Scenario: Class C Equipment shall not provide a Mode 3 caution alert when ... Mode 3 is inhibited. Given the aircraft is on a take-off segment Given Mode 3 is inhibited - When the height above terrain is 60.0 feet + When the height above terrain is equal 60.0 feet Given in the next phase - When the height above terrain is at 34.0 feet + When the height above terrain is equal 34.0 feet Then Mode 3 is armed Then a Mode 3 caution shall not be emitted diff --git a/taws_minimal/features/pda.feature b/taws_minimal/features/pda.feature index bf45d8b..f67416a 100644 --- a/taws_minimal/features/pda.feature +++ b/taws_minimal/features/pda.feature @@ -62,7 +62,7 @@ Feature: Premature Descent Alerting (PDA) Scenario: Class C Equipment shall not provide a PDA caution alert when ... PDA is inhibited. Given PDA is inhibited When the distance to runway is 1.0 NM - And the height above terrain is 10.0 feet + And the height above terrain is equal 10.0 feet Then a PDA caution is no emitted Rule: PDA is armed and not-inhibited and an alert is active diff --git a/taws_minimal/features/self_test.feature b/taws_minimal/features/self_test.feature deleted file mode 100644 index c76cf99..0000000 --- a/taws_minimal/features/self_test.feature +++ /dev/null @@ -1,38 +0,0 @@ -Feature: Self-Test (MOPS_001) - TAWS Equipment shall (TAWS_MOPS_001) include a self-test function that - provides indications of equipment condition during operation. This self-test - function consists of continuous and initiated tests. - - @MOPS_002 @MOPS_003 @MOPS_004 - Scenario: Continuos Self-Test - When a failure is detected by the continuos monitoring - Then the TAWS reports the failure - And disarms all affected functions - - # can be done using interaction with the crew - @MOPS_005 - Scenario Outline: Initiated Self-Test - When the self-test is initiated - Then the TAWS must verify system operation and integrity of - - Examples: - | capability | - | aural alerting | - | visual alerting | - | altitude callouts | - | terrain display outputs | - | fault reporting | - - @MOPS_006 - Scenario: Initiated Self-Test - Given the self-test is initiated - When the initiated self-test detects a failure - Then the failure must be reported - - #Scenario: Automatic Arming (MOPS_007) - - Scenario: Input Data Smoothing - When the rate of input data reduces or stagnates - Then the delays to alert onset do not - -# vim: set ts=2 sw=2 expandtab: retab: expandtab # diff --git a/taws_minimal/src/lib.rs b/taws_minimal/src/lib.rs index 116fe42..846314c 100644 --- a/taws_minimal/src/lib.rs +++ b/taws_minimal/src/lib.rs @@ -1,328 +1,40 @@ +use opentaws::class_c::*; use opentaws::prelude::*; -#[macro_use] -mod macros; +pub type AlertSource = opentaws::class_c::ClassC_Source; +pub type Alert = opentaws::alerts::Alert; +pub type Alerts = opentaws::alerts::Alerts; -/// This is the number of different alerts in an alert_state for MinimalTAWS -const ALERT_STATE_SIZE: usize = 8; - -/// Represents one instance of a TAWS -#[derive(Debug)] -pub struct MinimalTaws<'a> { - /// `true` if the TAWS is armed - /// - /// There is no specific condition for changing this to `false`. - pub armed: bool, - config: &'a TawsConfig<'a>, - ffac: functionalities::Ffac, - flta: functionalities::Flta, - mode1: functionalities::Mode1, - mode2: functionalities::Mode2, - mode3: functionalities::Mode3, - mode4: functionalities::Mode4, - mode5: functionalities::Mode5, - pda: functionalities::Pda<'a>, +pub struct MinimalTaws { + functionalities: ClassC, } -impl<'a> MinimalTaws<'a> { - functionalities![Ffac, Flta, Mode1, Mode2, Mode3, Mode4, Mode5, Pda]; - - /// Create a new instance of `Taws` - /// - /// # Arguments - /// - /// * `config` - The configuration which this TAWS instance shall use - /// - /// # Example - /// - /// ``` - /// use opentaws::prelude::*; - /// use taws_minimal::MinimalTaws; - /// - /// let config = TawsConfig::default(); - /// let taws = MinimalTaws::new(&config); - /// ``` - pub fn new(config: &'a TawsConfig) -> Self { - let ffac = functionalities::Ffac::new(config); - let flta = functionalities::Flta::new(config); - let mode1 = functionalities::Mode1::new(config); - let mode2 = functionalities::Mode2::new(config); - let mode3 = functionalities::Mode3::new(config); - let mode4 = functionalities::Mode4::new(config); - let mode5 = functionalities::Mode5::new(config); - let pda = functionalities::Pda::new(config); - +impl MinimalTaws { + pub fn new() -> Self { Self { - armed: true, - config, - ffac, - flta, - mode1, - mode2, - mode3, - mode4, - mode5, - pda, + functionalities: ClassC::new(), } } } -impl<'a> Taws for MinimalTaws<'a> { - /// Returns `true` if the alert system is armed - /// - /// # Arguments - /// - /// * `alert_system` - The alert system whiches armed state shall be checked - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let taws = MinimalTaws::new(&config); - /// if taws.is_armed(Alert::Mode1) { - /// // ... - /// } - /// ``` - fn is_armed(&self, alert_system: Alert) -> bool { - self.get_functionality(alert_system).is_armed() - } +impl Taws for MinimalTaws { + type AlertSource = AlertSource; - /// Arms a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let mut taws = MinimalTaws::new(&config); - /// taws.arm(Alert::Mode1); - /// - /// assert!(taws.is_armed(Alert::Mode1)); - /// ``` - fn arm(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).arm(); - } + type Alert = Alert; - /// Disarms a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let mut taws = MinimalTaws::new(&config); - /// taws.disarm(Alert::Mode1); - /// - /// assert_eq!(taws.is_armed(Alert::Mode1), false); - /// ``` - fn disarm(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).disarm() - } + type Alerts = Alerts; - /// Returns `true` if the alert system is inhibited - /// - /// # Arguments - /// - /// * `alert_system` - The alert system whiches inhibited state shall be checked - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let taws = MinimalTaws::new(&config); - /// if taws.is_inhibited(Alert::Mode1) { - /// // ... - /// } - /// ``` - fn is_inhibited(&self, alert_system: Alert) -> bool { - self.get_functionality(alert_system).is_inhibited() - } - - /// Inhibit a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be inhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let mut taws = MinimalTaws::new(&config); - /// taws.inhibit(Alert::Mode1); - /// - /// assert!(taws.is_inhibited(Alert::Mode1)); - /// ``` - fn inhibit(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).inhibit() - } + type Functionalities = ClassC; - /// Uninhibit a specific alert system - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be uninhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let mut taws = MinimalTaws::new(&config); - /// taws.uninhibit(Alert::Mode1); - /// - /// assert_eq!(taws.is_inhibited(Alert::Mode1), false); - /// ``` - fn uninhibit(&mut self, alert_system: Alert) { - self.get_mut_functionality(alert_system).uninhibit() + fn functionalities( + &self, + ) -> &dyn TawsFunctionalities { + &self.functionalities } - /// Process a new aircraft state - /// - /// This method must be called regularly for the TAWS to function properly! - /// No warnings will be emitted without calling this function. - /// - /// # Arguments - /// - /// * `alert_system` - The alert system which shall be uninhibited - /// - /// # Example - /// - /// ``` - /// # use opentaws::prelude::*; - /// # use taws_minimal::MinimalTaws; - /// # let config = TawsConfig::default(); - /// # let mut taws = MinimalTaws::new(&config); - /// let aicraft_state = AircraftState::default(); - /// - /// let alert_state = taws.process(&aicraft_state); - /// println!("Received AlertState: {:?}", alert_state); - /// ``` - fn process(&mut self, state: &AircraftState) -> AlertState { - let mut alert_state = AlertState::default(); - - for (alert, alert_system) in self - .functionality_mut_array() - .iter_mut() - .filter(|(_, alert_system)| !alert_system.is_inhibited()) - { - if let Some((alert_level, _priority)) = alert_system.process(state) { - alert_state.insert(*alert, alert_level); - } - } - - alert_state - } -} - -#[cfg(test)] -mod test { - use super::*; - use aviation_database::reference::AirportDatabaseImpl; - - #[test] - fn check_all_alert_systems() { - let airport_database = AirportDatabaseImpl::default(); - let config = TawsConfig { - terrain_server: &airport_database, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - }; - let taws = MinimalTaws::new(&config); - let _ = taws.is_armed(Alert::Ffac); - let _ = taws.is_armed(Alert::Flta); - let _ = taws.is_armed(Alert::Mode1); - let _ = taws.is_armed(Alert::Mode2); - let _ = taws.is_armed(Alert::Mode3); - let _ = taws.is_armed(Alert::Mode4); - let _ = taws.is_armed(Alert::Mode5); - let _ = taws.is_armed(Alert::Pda); - } - - #[test] - fn check_edge_case_1() { - use uom::si::{ - angle::{degree, revolution}, - length::meter, - time::second, - velocity::meter_per_second, - }; - - let airport_database = AirportDatabaseImpl::default(); - let config = TawsConfig { - terrain_server: &airport_database, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - }; - let mut taws = MinimalTaws::new(&config); - //Angle::new::(1.0) - - let input = AircraftState { - timestamp: Time::new::(-1192551353.0), - altitude: Length::new::(4608227.6136), - altitude_ground: Length::new::(45.72), - climb_rate: Velocity::new::(-3533302.6819200004), - position_lat: Angle::new::(-24748089.039895818), - position_lon: Angle::new::(-19226236.894961454), - speed_ground: Velocity::new::(1060688081.2833334), - speed_air: Velocity::new::(-87219196.62777779), - heading: Angle::new::(-31215539.612156395), - pitch: Angle::new::(-15680644.065499812), - roll: Angle::new::(10762607.494661978), - steep_approach: true, - precision_approach: false, - go_around: false, - take_off: false, - }; - let output = taws.process(&input); - - assert_eq!( - output.priority_alert(), - Some((Alert::Mode1, AlertLevel::Warning)) - ); + fn functionalities_mut( + &mut self, + ) -> &mut dyn TawsFunctionalities { + &mut self.functionalities } - // ———— [!] Step failed: ——————————————————————————  p_tester/src/tester.rs:220:25 - // Aicraft state that violated the scenario: AircraftState { - // timestamp: -1192551353.0 s^1, - // altitude: 4608227.6136 m^1, - // altitude_ground: 45.72 m^1, - // climb_rate: -3533302.6819200004 m^1 s^-1, - // position_lat: -24748089.039895818, - // position_lon: -19226236.894961454, - // speed_ground: 1060688081.2833334 m^1 s^-1, - // speed_air: -87219196.62777779 m^1 s^-1, - // heading: -31215539.612156395, - // pitch: -15680644.065499812, - // roll: 10762607.494661978, - // steep_approach: true, - // } - // alerts emitted: AlertState { - // all_alerts: [ - // None, - // None, - // None, - // None, - // None, - // None, - // None, - // None, - // ], - // } } diff --git a/taws_minimal/src/macros.rs b/taws_minimal/src/macros.rs deleted file mode 100644 index 5b5e39a..0000000 --- a/taws_minimal/src/macros.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Allow us to iterate over the functionalities for a lack of inline comptime loop unrolling -macro_rules! functionalities { - [$( $functionality_name:tt ),+] => { - /// - fn get_functionality(&self, alert_system: Alert) -> &dyn AlertSystem<'a> { - match alert_system { - $( - $functionality_name => casey::lower!(&self.$functionality_name), - )+ - } - } - - fn get_mut_functionality(&mut self, alert_system: Alert) -> &mut dyn AlertSystem<'a> { - match alert_system { - $( - $functionality_name => casey::lower!(&mut self.$functionality_name), - )+ - } - } - - fn functionality_mut_array(&mut self)->[(Alert, &mut dyn AlertSystem<'a>); count!($($functionality_name)+)]{ - [ $( - ( - $functionality_name, - casey::lower!(&mut self.$functionality_name) as &mut dyn AlertSystem - ), - )+ ] - } - }; -} - -// Count stuff, for a lack of advanced const generics -macro_rules! count { - () => (0usize); - ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); -} diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index bc080ec..281762b 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -1,9 +1,10 @@ //mod constraints; mod util; -use cucumber::{given, then, when, WorldInit}; +use cucumber::{given, then, when, World}; use opentaws::prelude::*; +use taws_minimal::{Alert, AlertSource}; use uom::si::f64::{Length, Velocity}; use uom::si::{length, velocity}; use util::aircraft_state::AircraftStateGenerator; @@ -14,7 +15,7 @@ use util::world::MyWorld; use crate::util::constraints::BouncingClamp; fn main() { - smol::block_on(MyWorld::run("features")); + futures::executor::block_on(MyWorld::run("features")); } // TODO check for parallel testing @@ -26,21 +27,24 @@ fn given_new_phase(world: &mut MyWorld) { world.next_phase(); } -#[given(expr = "the plane {maybe} flying")] -fn given_flying(_world: &mut MyWorld, _maybe: MaybeParameter) {} - -#[given(expr = "{alert} {maybe} armed")] -fn given_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { - let alert: Alert = alert.into(); - match maybe.into() { - true => world.taws.arm(alert), - false => world.taws.disarm(alert), +#[given(expr = "the aircraft {maybe} on a(n) {flight-segment} segment")] +fn given_segment(world: &mut MyWorld, maybe: MaybeParameter, segment: FlightSegmentParameter) { + let maybe: bool = maybe.into(); + let mut segment: FlightSegment = segment.into(); + // use cruise as default flight segment => "not on a take-off segment" means "on a cruise segment". + if !maybe { + assert!( + segment != FlightSegment::Cruise, + "Constaint: \"the aircraft is not on a cruise segment\" is not supported." + ); + segment = FlightSegment::Cruise; } -} + world.phases[world.phase].add_situation_constraint(segment); +} #[given(expr = "{alert} {maybe} inhibited")] -fn given_alert_inhibited(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { - let alert: Alert = alert.into(); +fn given_alert_inhibited(world: &mut MyWorld, alert: AlertSourceParameter, maybe: MaybeParameter) { + let alert: AlertSource = alert.into(); match maybe.into() { true => world.taws.inhibit(alert), false => world.taws.uninhibit(alert), @@ -58,18 +62,14 @@ fn given_precision_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) world.phases[world.phase].add_precision_approach_constraint(!maybe); } -#[given(expr = "take-off {maybe} selected")] -fn given_take_off(world: &mut MyWorld, maybe: MaybeParameter) { - world.phases[world.phase].add_take_off_constraint(maybe.into()); -} - -#[given(expr = "go around {maybe} selected")] -fn given_go_around(world: &mut MyWorld, maybe: MaybeParameter) { - world.phases[world.phase].add_go_around_constraint(maybe.into()); +#[given(expr = "circling approach {maybe} selected")] +fn given_circling_approach_selected(world: &mut MyWorld, maybe: MaybeParameter) { + let maybe: bool = maybe.into(); + world.phases[world.phase].add_circling_approach_constraint(!maybe); } -#[given(expr = "the height above terrain is {constraint} foot")] -#[when(expr = "the height above terrain is {constraint} foot")] +#[given(expr = "the height above terrain is {constraint} feet")] +#[when(expr = "the height above terrain is {constraint} feet")] fn given_height_above_terrain(world: &mut MyWorld, height_above_terrain: ConstraintParameter) { let height_above_terrain: Constraint = height_above_terrain.into(); @@ -101,38 +101,23 @@ fn when_rate_of_descent(world: &mut MyWorld, rate_of_descent: ConstraintParamete world.phases[world.phase].add_climb_rate_constraint(climb_rate); } -#[when(expr = "the height above terrain is {constraint} feet")] -fn when_height_above_terrain(world: &mut MyWorld, height_above_ground: ConstraintParameter) { - let height_above_ground: Constraint = height_above_ground.into(); - - let unit = Length::new::(1.0); - let height_above_ground = match height_above_ground { - Constraint::AtLeast(a) => Constraint::AtLeast(a * unit), - Constraint::AtMost(a) => Constraint::AtMost(a * unit), - Constraint::Equal(a) => Constraint::Equal(a * unit), - Constraint::InRange(a, b) => Constraint::InRange(a * unit, b * unit), - Constraint::NotInRange(a, b) => Constraint::NotInRange(a * unit, b * unit), - }; - - world.phases[world.phase].add_altitude_ground_constraint(height_above_ground); -} - -#[then(expr = "{alert} {maybe} be armed")] -fn then_alert_armed(world: &mut MyWorld, alert: AlertParameter, maybe: MaybeParameter) { - let mut state = AircraftStateGenerator::default().next().unwrap(); +#[then(expr = "{alert} {maybe}( be) armed")] +fn then_alert_armed(world: &mut MyWorld, alert: AlertSourceParameter, maybe: MaybeParameter) { + let mut state = world.next_aircraft_state(); for phase in world.phases.iter() { phase.apply_to::(&mut state); - let _alerts = world.taws.process(&state); + let _alerts = world.taws.process(&state.normalize()); + _alerts.unwrap(); } let is_armed = world.taws.is_armed(alert.into()); assert_eq!(is_armed, maybe.into()) } -#[then(expr = "a {alert} {alert_level} alert {maybe} emitted {constraint} seconds")] +#[then(expr = "a {alert} {alert_level} {maybe}( be) emitted {constraint} seconds")] fn then_alert_emitted_within( world: &mut MyWorld, - alert: AlertParameter, + alert: AlertSourceParameter, level: AlertLevelParameter, should_emit: MaybeParameter, _time: ConstraintParameter, @@ -140,31 +125,30 @@ fn then_alert_emitted_within( then_alert_emitted(world, alert, level, should_emit) } -#[then(expr = "a {alert} {alert_level} alert {maybe} emitted( at all)")] +#[then(expr = "a {alert} {alert_level} {maybe}( be) emitted( at all)")] fn then_alert_emitted( world: &mut MyWorld, - alert: AlertParameter, - level: AlertLevelParameter, + alert_src: AlertSourceParameter, + min_level: AlertLevelParameter, should_emit: MaybeParameter, ) { - let alert: Alert = alert.into(); - let level: AlertLevel = level.into(); + let alert_src: AlertSource = alert_src.into(); + let min_level: AlertLevel = min_level.into(); let should_emit: bool = should_emit.into(); - let mut aircraft_states: Vec = AircraftStateGenerator::default() - .take(world.test_length) - .collect(); + let mut aircraft_states: Vec = world.next_aircraft_states(world.test_length); for state in aircraft_states.iter_mut() { for (i, phase) in world.phases.iter().enumerate() { phase.apply_to::(state); - let alert_state = world.taws.process(state); + let alerts = world.taws.process(&state.normalize()).unwrap(); if i < world.phases.len() - 1 { continue; } - let emitted = alert_state.iter().any(|(a, l)| a == alert && l <= level); + let emitted = alerts.is_alert_active(alert_src, min_level); + assert_eq!(emitted, should_emit); } } diff --git a/taws_minimal/tests/util/aircraft_state.rs b/taws_minimal/tests/util/aircraft_state.rs index e40d610..ff8e489 100644 --- a/taws_minimal/tests/util/aircraft_state.rs +++ b/taws_minimal/tests/util/aircraft_state.rs @@ -1,29 +1,35 @@ +use std::marker::PhantomData; + use arbitrary::{Arbitrary, Unstructured}; use opentaws::prelude::*; use rand::RngCore; +use super::constraints::{AircraftStateConstraints, BouncingClamp}; + #[derive(Debug, Clone)] struct AircraftStateWrapper(AircraftState); impl<'a> Arbitrary<'a> for AircraftStateWrapper { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { - Ok(AircraftStateWrapper(AircraftState { - timestamp: Time::new::(::arbitrary(u)? as f64), - altitude: Length::new::(::arbitrary(u)? as f64), - altitude_ground: Length::new::(::arbitrary(u)? as f64), - climb_rate: Velocity::new::(::arbitrary(u)? as f64), - position_lat: Angle::new::(::arbitrary(u)? as f64), - position_lon: Angle::new::(::arbitrary(u)? as f64), - speed_ground: Velocity::new::(::arbitrary(u)? as f64), - speed_air: Velocity::new::(::arbitrary(u)? as f64), - heading: Angle::new::(::arbitrary(u)? as f64), - pitch: Angle::new::(::arbitrary(u)? as f64), - roll: Angle::new::(::arbitrary(u)? as f64), - steep_approach: u.arbitrary()?, - precision_approach: u.arbitrary()?, - go_around: u.arbitrary()?, - take_off: u.arbitrary()?, - })) + let mut state = AircraftState::default(); + + *state.timestamp_mut() = Time::new::(::arbitrary(u)? as f64); + *state.position_latitude_mut() = + Angle::new::(::arbitrary(u)? as f64); + *state.position_longitude_mut() = + Angle::new::(::arbitrary(u)? as f64); + *state.altitude_mut() = Length::new::(::arbitrary(u)? as f64); + *state.altitude_ground_mut() = + Length::new::(::arbitrary(u)? as f64); + *state.speed_ground_mut() = Velocity::new::(::arbitrary(u)? as f64); + *state.speed_air_mut() = Velocity::new::(::arbitrary(u)? as f64); + *state.climb_rate_mut() = + Velocity::new::(::arbitrary(u)? as f64); + *state.heading_mut() = Angle::new::(::arbitrary(u)? as f64); + *state.track_mut() = Angle::new::(::arbitrary(u)? as f64); + *state.situation_mut() = Some(FlightSegment::Cruise); + + Ok(AircraftStateWrapper(state)) } fn size_hint(_depth: usize) -> (usize, Option) { @@ -35,10 +41,11 @@ impl<'a> Arbitrary<'a> for AircraftStateWrapper { type Prng = rand_pcg::Mcg128Xsl64; pub struct AircraftStateGenerator(pub Prng); + impl Default for AircraftStateGenerator { - fn default() -> Self { - Self(Prng::new(0xcafef00dd15ea5e5)) - } + fn default() -> Self { + Self(Prng::new(0xcafef00dd15ea5e5)) + } } impl Iterator for AircraftStateGenerator { @@ -52,6 +59,7 @@ impl Iterator for AircraftStateGenerator { } let mut u = Unstructured::new(&buf); - Some(AircraftStateWrapper::arbitrary(&mut u).unwrap().0) // the unwrap is safe, we guarantee that enough bytes are available + let mut state = AircraftStateWrapper::arbitrary(&mut u).unwrap().0; // the unwrap is safe, we guarantee that enough bytes are available + Some(state) } } diff --git a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs index 704a8bf..f44a7f2 100644 --- a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs @@ -10,13 +10,9 @@ pub struct AircraftStateConstraints { climb_rate: Option>, speed_air: Option>, heading: Option>, - pitch: Option>, - roll: Option>, + track: Option>, - steep_approach: Option, - precision_approach: Option, - go_around: Option, - take_off: Option, + situation: Option, } impl AircraftStateConstraints { @@ -45,18 +41,14 @@ impl AircraftStateConstraints { + ConstraintEnforcer + Default, { - Self::apply::(&self.altitude, &mut state.altitude); - Self::apply::(&self.altitude_ground, &mut state.altitude_ground); - Self::apply::(&self.climb_rate, &mut state.climb_rate); - Self::apply::(&self.speed_air, &mut state.speed_air); - Self::apply::(&self.heading, &mut state.heading); - Self::apply::(&self.pitch, &mut state.pitch); - Self::apply::(&self.roll, &mut state.roll); - - state.steep_approach = self.steep_approach.unwrap_or(state.steep_approach); - state.precision_approach = self.precision_approach.unwrap_or(state.precision_approach); - state.go_around = self.go_around.unwrap_or(state.go_around); - state.take_off = self.take_off.unwrap_or(state.take_off); + Self::apply::(&self.altitude, state.altitude_mut()); + Self::apply::(&self.altitude_ground, state.altitude_ground_mut()); + Self::apply::(&self.climb_rate, state.climb_rate_mut()); + Self::apply::(&self.speed_air, state.speed_air_mut()); + Self::apply::(&self.heading, state.heading_mut()); + Self::apply::(&self.track, state.track_mut()); + + *state.situation_mut() = self.situation.or(*state.situation()); } pub fn add_altitude_constraint(&mut self, c: Constraint) { @@ -94,33 +86,25 @@ impl AircraftStateConstraints { } } - pub fn add_pitch_constraint(&mut self, c: Constraint) { - self.pitch = match &self.pitch { - Some(pitch) => Some(pitch.merge(&c).unwrap()), - None => Some(c), - } - } - - pub fn add_roll_constraint(&mut self, c: Constraint) { - self.roll = match &self.roll { - Some(roll) => Some(roll.merge(&c).unwrap()), - None => Some(c), - } - } - - pub fn add_steep_approach_constraint(&mut self, c: bool) { - self.steep_approach = Some(c); - } - - pub fn add_precision_approach_constraint(&mut self, c: bool) { - self.precision_approach = Some(c); + pub fn add_situation_constraint(&mut self, situation: FlightSegment) { + self.situation = Some(situation); } - pub fn add_go_around_constraint(&mut self, c: bool) { - self.go_around = Some(c); - } - - pub fn add_take_off_constraint(&mut self, c: bool) { - self.take_off = Some(c); - } + pub fn add_steep_approach_constraint(&mut self, is_steep: bool) { + if let Some(FlightSegment::Landing { ref mut steep_approach, .. }) = self.situation { + *steep_approach = is_steep; + } + } + + pub fn add_precision_approach_constraint(&mut self, is_precision: bool) { + if let Some(FlightSegment::Landing { ref mut precision_approach, .. }) = self.situation { + *precision_approach = is_precision; + } + } + + pub fn add_circling_approach_constraint(&mut self, is_circling: bool) { + if let Some(FlightSegment::Landing { ref mut circling_approach, .. }) = self.situation { + *circling_approach = is_circling; + } + } } diff --git a/taws_minimal/tests/util/constraints/airport_database.rs b/taws_minimal/tests/util/constraints/airport_database.rs deleted file mode 100644 index 14faee0..0000000 --- a/taws_minimal/tests/util/constraints/airport_database.rs +++ /dev/null @@ -1,8 +0,0 @@ -use aviation_database::{AirportDatabase, Runway}; - -#[derive(Debug, Default)] -pub struct ConstraintAirportDatabase; - -impl AirportDatabase for ConstraintAirportDatabase { - type RunwayIterator = core::iter::Empty; -} diff --git a/taws_minimal/tests/util/constraints/mod.rs b/taws_minimal/tests/util/constraints/mod.rs index 0f87fe7..2f388d4 100644 --- a/taws_minimal/tests/util/constraints/mod.rs +++ b/taws_minimal/tests/util/constraints/mod.rs @@ -1,9 +1,7 @@ mod aircraft_state_constraints; -mod airport_database; mod constraint; mod constraint_enforcement; pub use aircraft_state_constraints::*; -pub use airport_database::*; pub use constraint::*; pub use constraint_enforcement::*; diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs index 2db10e8..0a969fa 100644 --- a/taws_minimal/tests/util/parameters.rs +++ b/taws_minimal/tests/util/parameters.rs @@ -1,10 +1,12 @@ use std::str::FromStr; -use cucumber::Parameter; +use cucumber::{Parameter}; use lazy_static::lazy_static; -use opentaws::{Alert, AlertLevel}; use regex::Regex; +use opentaws::prelude::*; +use taws_minimal::AlertSource; + use super::constraints::Constraint; pub struct MaybeParameter(bool); @@ -34,35 +36,32 @@ impl Parameter for MaybeParameter { const REGEX: &'static str = r"(?:is|should|shall)\s*(?:not)?"; } -pub struct AlertParameter(Alert); +pub struct AlertSourceParameter(AlertSource); -impl FromStr for AlertParameter { +impl FromStr for AlertSourceParameter { type Err = String; fn from_str(s: &str) -> Result { let mut alert = s.trim().to_lowercase(); alert.retain(|c| !c.is_whitespace()); match alert.as_str() { - "ffac" => Ok(Self(Alert::Ffac)), - "flta" => Ok(Self(Alert::Flta)), - "mode1" => Ok(Self(Alert::Mode1)), - "mode2" => Ok(Self(Alert::Mode2)), - "mode3" => Ok(Self(Alert::Mode3)), - "mode4" => Ok(Self(Alert::Mode4)), - "mode5" => Ok(Self(Alert::Mode5)), - "pda" => Ok(Self(Alert::Pda)), + "ffac" => Ok(Self(AlertSource::Ffac)), + //"flta" => Ok(Self(Alert::Flta)), + "mode1" => Ok(Self(AlertSource::Mode1)), + "mode3" => Ok(Self(AlertSource::Mode3)), + "pda" => Ok(Self(AlertSource::Pda)), _ => Err(format!("unknown alert: {s}")), } } } -impl From for Alert { - fn from(alert_param: AlertParameter) -> Self { +impl From for AlertSource { + fn from(alert_param: AlertSourceParameter) -> Self { alert_param.0 } } -impl Parameter for AlertParameter { +impl Parameter for AlertSourceParameter { const NAME: &'static str = "alert"; const REGEX: &'static str = r"(?:[a-zA-Z]+\s*[0-9]*)"; } @@ -102,7 +101,7 @@ impl FromStr for ConstraintParameter { fn from_str(s: &str) -> Result { const PATTERN: &str = concat!( - r"(?Pat least|at most|within|between|not between)", + r"(?Pequal|at least|at most|within|between|not between)", r"\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+)", r"(?:\s*and\s*(?P[+-]?(?:[0-9]*[.])?[0-9]+))?" ); @@ -126,6 +125,10 @@ impl FromStr for ConstraintParameter { .map_err(|_| "invalid quantity format")?; match typ { + "equal" => match q2 { + Some(_) => Err(format!("unexpected: {}", s)), + None => Ok(Self(Constraint::Equal(q1))) + }, "at least" => match q2 { Some(_) => Err(format!("unexpected: {}", s)), None => Ok(Self(Constraint::AtLeast(q1))), @@ -159,8 +162,38 @@ impl Parameter for ConstraintParameter { const NAME: &'static str = "constraint"; const REGEX: &'static str = concat!( - r"(?:at least|at most|within|between|not between)\s*", + r"(?:equal|at least|at most|within|between|not between)\s*", r"[+-]?(?:[0-9]*[.])?[0-9]+", r"(?:\s*and\s*[+-]?(?:[0-9]*[.])?[0-9]+)?" ); } + +pub struct FlightSegmentParameter(FlightSegment); + +impl From for FlightSegment { + fn from(segment: FlightSegmentParameter) -> Self { + segment.0 + } +} + +impl FromStr for FlightSegmentParameter { + type Err = String; + + fn from_str(s: &str) -> Result { + let mut segment = s.trim().to_lowercase(); + segment.retain(|c| !c.is_whitespace()); + match segment.as_str() { + "cruise" => Ok(Self(FlightSegment::Cruise)), + "take-off" => Ok(Self(FlightSegment::TakeOff)), + "approach" | "landing" => Ok(Self(FlightSegment::Landing { circling_approach: false, precision_approach: false, steep_approach: false })), + "go-around" => Ok(Self(FlightSegment::GoAround)), + _ => Err(format!("invalid flight segment: {}", s)), + } + } +} + +impl Parameter for FlightSegmentParameter { + const NAME: &'static str = "flight-segment"; + + const REGEX: &'static str = r"(?:cruise|take-off|landing|go-around|approach)"; +} diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs index 85545e6..092c5f0 100644 --- a/taws_minimal/tests/util/world.rs +++ b/taws_minimal/tests/util/world.rs @@ -1,41 +1,44 @@ -use std::convert::Infallible; - -use async_trait::async_trait; -use cucumber::WorldInit; +use cucumber::World; use opentaws::prelude::*; use taws_minimal::MinimalTaws; -use super::constraints::{AircraftStateConstraints, ConstraintAirportDatabase}; - -static AIRPORT_DATABASE: ConstraintAirportDatabase = ConstraintAirportDatabase {}; - -lazy_static::lazy_static! { - static ref TAWS_CONFIG: TawsConfig<'static> = TawsConfig{ - terrain_server: &AIRPORT_DATABASE, - max_climbrate: Velocity::new::(700.0), - max_climbrate_change: Acceleration::new::(100.0), - }; -} +use super::{aircraft_state::AircraftStateGenerator, constraints::AircraftStateConstraints}; -#[derive(WorldInit)] +#[derive(World)] pub struct MyWorld { - pub taws: MinimalTaws<'static>, + pub taws: MinimalTaws, pub phases: Vec, pub test_length: usize, pub phase: usize, + + pub taws_constraints: AircraftStateConstraints, + pub state_gen: AircraftStateGenerator, } -#[async_trait(?Send)] -impl cucumber::World for MyWorld { - type Error = Infallible; +impl Default for MyWorld { + fn default() -> Self { + let mut taws_constraints = AircraftStateConstraints::default(); + + let max_altitude_gnd = Length::new::(330_000.0); + taws_constraints.add_altitude_ground_constraint(super::constraints::Constraint::InRange( + Length::new::(0.0), + max_altitude_gnd, + )); - async fn new() -> Result { - Ok(Self { - taws: MinimalTaws::new(&TAWS_CONFIG), - phases: vec![AircraftStateConstraints::default()], - test_length: 10, + let min_max_climb_rate = Velocity::new::(680_000.0); + taws_constraints.add_climb_rate_constraint(super::constraints::Constraint::InRange( + -min_max_climb_rate, + min_max_climb_rate, + )); + + Self { + taws: MinimalTaws::new(), + phases: vec![taws_constraints.clone()], + test_length: 100, phase: 0, - }) + taws_constraints: taws_constraints.clone(), + state_gen: AircraftStateGenerator::default(), + } } } @@ -47,9 +50,15 @@ impl std::fmt::Debug for MyWorld { impl MyWorld { pub fn next_phase(&mut self) { - self.phases.push(AircraftStateConstraints::default()); + self.phases.push(self.taws_constraints.clone()); self.phase += 1; } -} -impl std::panic::UnwindSafe for MyWorld {} // This is a lie, but what they gonna do, panic? + pub fn next_aircraft_state(&mut self) -> AircraftState { + self.state_gen.next().unwrap() + } + + pub fn next_aircraft_states(&mut self, n: usize) -> Vec { + (0..n).map(|_| self.next_aircraft_state()).collect() + } +} From 35fe6fe3ba10a8e59b2c93b743e8568c00ae2a02 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 1 Nov 2022 15:07:08 +0100 Subject: [PATCH 50/73] wip --- rust-toolchain.toml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 2f47d05..0000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "stable-x86_64-pc-windows-msvc" -#channel = "nightly-x86_64-pc-windows-msvc" From 9d6ffc2587041a90098fe35faf8f0ed6d6c7442b Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Mon, 15 May 2023 15:42:41 +0200 Subject: [PATCH 51/73] fix --- Cargo.lock | 1453 +++++------------ Cargo.toml | 13 +- aviation_database/Cargo.lock | 247 --- aviation_database/Cargo.toml | 26 - aviation_database/README.md | 7 - aviation_database/build.rs | 152 -- aviation_database/src/consts.rs | 5 - aviation_database/src/lib.rs | 216 --- aviation_database/src/reference.rs | 8 - kd_tree/Cargo.toml | 12 - kd_tree/README.md | 8 - kd_tree/src/lib.rs | 252 --- kd_tree_sort/Cargo.toml | 23 - kd_tree_sort/README.md | 19 - kd_tree_sort/benches/search.rs | 65 - kd_tree_sort/fuzz/.gitignore | 3 - kd_tree_sort/fuzz/Cargo.lock | 303 ---- kd_tree_sort/fuzz/Cargo.toml | 28 - .../fuzz/fuzz_targets/kd_tree_search.rs | 55 - kd_tree_sort/src/lib.rs | 205 --- opentaws/Cargo.toml | 18 +- opentaws/src/aircraft_state.rs | 60 +- opentaws/src/alerts.rs | 6 +- opentaws/src/class_c.rs | 9 +- opentaws/src/class_c/ffac.rs | 10 +- opentaws/src/class_c/mode1.rs | 9 +- opentaws/src/class_c/mode3.rs | 19 +- opentaws/src/class_c/pda.rs | 7 +- opentaws/src/lib.rs | 5 +- opentaws/src/prelude.rs | 19 +- taws_minimal/Cargo.toml | 48 +- taws_minimal/src/lib.rs | 6 + taws_minimal/tests/cucumber.rs | 6 +- taws_minimal/tests/util/aircraft_state.rs | 37 +- .../constraints/aircraft_state_constraints.rs | 43 +- taws_minimal/tests/util/world.rs | 12 +- 36 files changed, 546 insertions(+), 2868 deletions(-) delete mode 100644 aviation_database/Cargo.lock delete mode 100644 aviation_database/Cargo.toml delete mode 100644 aviation_database/README.md delete mode 100644 aviation_database/build.rs delete mode 100644 aviation_database/src/consts.rs delete mode 100644 aviation_database/src/lib.rs delete mode 100644 aviation_database/src/reference.rs delete mode 100644 kd_tree/Cargo.toml delete mode 100644 kd_tree/README.md delete mode 100644 kd_tree/src/lib.rs delete mode 100644 kd_tree_sort/Cargo.toml delete mode 100644 kd_tree_sort/README.md delete mode 100644 kd_tree_sort/benches/search.rs delete mode 100644 kd_tree_sort/fuzz/.gitignore delete mode 100644 kd_tree_sort/fuzz/Cargo.lock delete mode 100644 kd_tree_sort/fuzz/Cargo.toml delete mode 100644 kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs delete mode 100644 kd_tree_sort/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 6b9e2ba..d28399a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "ahash" version = "0.7.6" @@ -21,132 +15,131 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] [[package]] -name = "anyhow" -version = "1.0.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" - -[[package]] -name = "approx" -version = "0.5.1" +name = "aho-corasick" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ - "num-traits", + "memchr", ] [[package]] -name = "arbitrary" -version = "1.2.0" +name = "anstream" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ - "derive_arbitrary", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", ] [[package]] -name = "array-init" -version = "2.0.1" +name = "anstyle" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] -name = "async-trait" -version = "0.1.58" +name = "anstyle-parse" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ - "proc-macro2", - "quote", - "syn", + "utf8parse", ] [[package]] -name = "atomic-polyfill" -version = "0.1.10" +name = "anstyle-query" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "critical-section", + "windows-sys 0.48.0", ] [[package]] -name = "atty" -version = "0.2.14" +name = "anstyle-wincon" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "anstyle", + "windows-sys 0.48.0", ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "anyhow" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] -name = "aviation_database" -version = "0.1.0" +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ - "anyhow", - "csv", - "kd_tree", - "kd_tree_sort", - "ordered-float", - "proc-macro2", - "quote", - "rayon", - "regex", - "serde", - "serde_json", - "uneval", - "uom", - "ureq", + "num-traits", ] [[package]] -name = "bare-metal" -version = "0.2.5" +name = "arbitrary" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" dependencies = [ - "rustc_version 0.2.3", + "derive_arbitrary", ] [[package]] -name = "bare-metal" -version = "1.0.0" +name = "async-trait" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] [[package]] -name = "base64" -version = "0.13.0" +name = "atomic-polyfill" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] [[package]] -name = "bit_field" -version = "0.10.1" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] [[package]] -name = "bitfield" -version = "0.13.2" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" @@ -156,51 +149,31 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" -version = "0.2.17" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" dependencies = [ - "lazy_static", "memchr", - "regex-automata", "serde", ] -[[package]] -name = "bumpalo" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - [[package]] name = "bytecount" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" -[[package]] -name = "bytemuck" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" - [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -208,231 +181,94 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chunked_transfer" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" - [[package]] name = "clap" -version = "2.34.0" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" dependencies = [ - "bitflags", - "textwrap 0.11.0", - "unicode-width", + "clap_builder", + "clap_derive", + "once_cell", ] [[package]] -name = "clap" -version = "4.0.18" +name = "clap_builder" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" dependencies = [ - "atty", + "anstream", + "anstyle", "bitflags", - "clap_derive", "clap_lex", - "once_cell", "strsim", - "termcolor", - "terminal_size 0.2.1", + "terminal_size", ] [[package]] name = "clap_derive" -version = "4.0.18" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ - "heck 0.4.0", - "proc-macro-error", + "heck 0.4.1", "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" dependencies = [ "encode_unicode", "lazy_static", "libc", - "terminal_size 0.1.17", "unicode-width", - "winapi", -] - -[[package]] -name = "cortex-m" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0" -dependencies = [ - "bare-metal 0.2.5", - "bitfield", - "embedded-hal", - "volatile-register", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "criterion" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" -dependencies = [ - "atty", - "cast", - "clap 2.34.0", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" -dependencies = [ - "cast", - "itertools", + "windows-sys 0.42.0", ] [[package]] name = "critical-section" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" -dependencies = [ - "bare-metal 1.0.0", - "cfg-if", - "cortex-m", - "riscv", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "ctor" -version = "0.1.26" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +checksum = "dd4056f63fce3b82d852c3da92b08ea59959890813a7f4ce9c0ff85b10cf301b" dependencies = [ "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "cucumber" -version = "0.15.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56264a57a9b7207418f64e09dec7805cd4264b98c762150d3769171fb8a6fee5" +checksum = "a845da7c9fb958144700201d22e3f61f55114f9e269c13f03fe179d9da500984" dependencies = [ "anyhow", "async-trait", "atty", - "clap 4.0.18", + "clap", "console", "cucumber-codegen", "cucumber-expressions", @@ -449,13 +285,14 @@ dependencies = [ "once_cell", "regex", "sealed 0.4.0", + "smart-default", ] [[package]] name = "cucumber-codegen" -version = "0.15.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f965514ac959efa875c8b17de1510d521aed75346ced61af1307968aea6f0f92" +checksum = "0dfb841fe8742f57fbe94738a189022e7dc858f2560c7fba5da44dc945a139e1" dependencies = [ "cucumber-expressions", "inflections", @@ -463,7 +300,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn", + "syn 1.0.109", "synthez", ] @@ -478,18 +315,18 @@ dependencies = [ "nom", "nom_locate", "regex", - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "derive_arbitrary" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4903dff04948f22033ca30232ab8eca2c3fc4c913a8b6a34ee5199699814817f" +checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -500,30 +337,20 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "drain_filter_polyfill" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9f76bdd86dfc8d64eecb0484d02ad4cf0e6767d4682f686d1b0580b6c27f82" +checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" [[package]] name = "either" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" - -[[package]] -name = "embedded-hal" -version = "0.2.7" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "encode_unicode" @@ -533,13 +360,13 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -552,37 +379,17 @@ dependencies = [ "libc", ] -[[package]] -name = "flate2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - [[package]] name = "futures" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -595,9 +402,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -605,15 +412,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -622,38 +429,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -669,9 +476,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -684,35 +491,35 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8f8f49b2b547ec22cc4d99f3bf30d4889ef0dbaa231c0736eeaf20efb5a38e" dependencies = [ - "heck 0.4.0", + "heck 0.4.1", "peg", "quote", "serde", "serde_json", - "syn", - "textwrap 0.16.0", + "syn 1.0.109", + "textwrap", "thiserror", "typed-builder", ] [[package]] name = "ghost" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a" +checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "globset" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ - "aho-corasick", + "aho-corasick 0.7.20", "bstr", "fnv", "log", @@ -730,12 +537,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "hash32" version = "0.2.1" @@ -762,8 +563,8 @@ checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.0", - "spin 0.9.4", + "rustc_version", + "spin 0.9.8", "stable_deref_trait", ] @@ -778,9 +579,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -792,29 +593,23 @@ dependencies = [ ] [[package]] -name = "humantime" -version = "2.1.0" +name = "hermit-abi" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] -name = "idna" -version = "0.2.3" +name = "humantime" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "ignore" -version = "0.4.18" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" dependencies = [ - "crossbeam-utils", "globset", "lazy_static", "log", @@ -834,9 +629,9 @@ checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" [[package]] name = "inventory" -version = "0.3.2" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e21e0a36a4dc4b469422ee17f715e8313f4a637675656d6a13637954278c6f55" +checksum = "7741301a6d6a9b28ce77c0fb77a4eb116b6bc8f3bef09923f7743d059c4157d3" dependencies = [ "ctor", "ghost", @@ -844,9 +639,26 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "0.7.4" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e481ccbe3dea62107216d0d1138bb8ad8e5e5c43009a098bd1990272c497b0" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] [[package]] name = "itertools" @@ -859,64 +671,30 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] -name = "js-sys" -version = "0.3.59" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "wasm-bindgen", + "spin 0.5.2", ] [[package]] -name = "kd_tree" -version = "0.1.0" -dependencies = [ - "num", -] - -[[package]] -name = "kd_tree_sort" -version = "0.1.0" -dependencies = [ - "criterion", - "itertools", - "kd_tree", - "rand", - "rand_pcg", - "rayon", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", -] - -[[package]] -name = "libc" -version = "0.2.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libm" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "linked-hash-map" @@ -926,9 +704,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.0.46" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -949,60 +727,25 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "matrixmultiply" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" -dependencies = [ - "rawpointer", -] - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - [[package]] name = "nalgebra" -version = "0.31.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e0a04ce089f9401aac565c740ed30c46291260f27d4911fdbaa6ca65fa3044" +checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" dependencies = [ "approx", - "matrixmultiply", - "nalgebra-macros", "num-complex", "num-rational", "num-traits", @@ -1010,37 +753,11 @@ dependencies = [ "typenum", ] -[[package]] -name = "nalgebra-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -1048,33 +765,20 @@ dependencies = [ [[package]] name = "nom_locate" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37794436ca3029a3089e0b95d42da1f0b565ad271e4d3bb4bad0c7bb70b10605" +checksum = "b1e299bf5ea7b212e811e71174c5d1a5d065c4c0ad0c8691ecb1f97e3e66025e" dependencies = [ "bytecount", "memchr", "nom", ] -[[package]] -name = "num" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" -dependencies = [ - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - [[package]] name = "num-complex" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" dependencies = [ "num-traits", ] @@ -1089,17 +793,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.4.1" @@ -1121,63 +814,28 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "once_cell" -version = "1.13.1" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opentaws" version = "0.1.0" dependencies = [ - "aviation_database", "hash32", "heapless", "lazy_static", "nalgebra", - "ringbuffer", - "serde", - "serde_arrays", "uom", ] -[[package]] -name = "ordered-float" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" -dependencies = [ - "num-traits", -] - -[[package]] -name = "os_str_bytes" -version = "6.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" - [[package]] name = "paste" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "peg" @@ -1206,12 +864,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1224,78 +876,26 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "plotters" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" - -[[package]] -name = "plotters-svg" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" -dependencies = [ - "plotters-backend", -] - [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -1339,112 +939,28 @@ dependencies = [ "rand_core", ] -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "regex" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.1", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ringbuffer" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30a00730a27595dcf899dce512aa031dd650f86aafcb132fd8dd9f409b369d0" -dependencies = [ - "array-init", -] - -[[package]] -name = "riscv" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" -dependencies = [ - "bare-metal 1.0.0", - "bit_field", - "riscv-target", -] - -[[package]] -name = "riscv-target" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" +name = "regex-syntax" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rustc_version" @@ -1452,49 +968,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver", ] [[package]] name = "rustix" -version = "0.35.9" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c825b8aa8010eb9ee99b75f05e10180b9278d161583034d7574c9d617aeada" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rustls" -version = "0.20.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" -dependencies = [ - "log", - "ring", - "sct", - "webpki", + "windows-sys 0.48.0", ] [[package]] name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "safe_arch" -version = "0.6.0" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" -dependencies = [ - "bytemuck", -] +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -1511,16 +1006,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sealed" version = "0.3.0" @@ -1530,7 +1015,7 @@ dependencies = [ "heck 0.3.3", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1542,102 +1027,78 @@ dependencies = [ "heck 0.3.3", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "semver" -version = "0.9.0" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.143" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] -[[package]] -name = "serde_arrays" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.143" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ - "itoa 1.0.3", + "itoa", "ryu", "serde", ] [[package]] name = "simba" -version = "0.7.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48e45e5961033db030b56ad67aef22e9c908c493a6e8348c0a0f6b93433cd77" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ "approx", "num-complex", "num-traits", "paste", - "wide", ] [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] +[[package]] +name = "smart-default" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "smawk" version = "0.3.1" @@ -1652,9 +1113,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" -version = "0.9.4" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] @@ -1673,9 +1134,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -1688,7 +1160,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "033178d0acccffc5490021657006e6a8dd586ee9dc6f7c24e7608b125e568cb1" dependencies = [ - "syn", + "syn 1.0.109", "synthez-codegen", "synthez-core", ] @@ -1699,7 +1171,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69263462a40e46960f070618e20094ce69e783a41f86e54bc75545136afd597a" dependencies = [ - "syn", + "syn 1.0.109", "synthez-core", ] @@ -1712,7 +1184,7 @@ dependencies = [ "proc-macro2", "quote", "sealed 0.3.0", - "syn", + "syn 1.0.109", ] [[package]] @@ -1720,7 +1192,6 @@ name = "taws_minimal" version = "0.1.0" dependencies = [ "arbitrary", - "aviation_database", "cucumber", "futures", "lazy_static", @@ -1731,42 +1202,14 @@ dependencies = [ "uom", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "terminal_size" -version = "0.2.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8440c860cf79def6164e4a0a983bcc2305d82419177a0e0c71930d049e3ac5a1" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ "rustix", - "windows-sys", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", + "windows-sys 0.48.0", ] [[package]] @@ -1782,58 +1225,34 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - [[package]] name = "typed-builder" version = "0.10.0" @@ -1842,36 +1261,20 @@ checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uneval" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63cc5d2fd8648d7e2be86098f60c9ece7045cc710b3c1e226910e2f37d11dc73" -dependencies = [ - "serde", - "thiserror", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-linebreak" @@ -1883,20 +1286,11 @@ dependencies = [ "regex", ] -[[package]] -name = "unicode-normalization" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -1904,56 +1298,20 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "uom" -version = "0.33.0" -source = "git+https://github.com/wucke13/uom?branch=fix-missing-libm#80c05d4848c29f5d356477f2a0636c6ad15160b8" +version = "0.34.0" +source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4ddb11b11b11b333a98185c19336d16c85e22c9c" dependencies = [ "num-traits", - "serde", "typenum", ] [[package]] -name = "ureq" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" -dependencies = [ - "base64", - "chunked_transfer", - "flate2", - "log", - "once_cell", - "rustls", - "url", - "webpki", - "webpki-roots", -] - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "vcell" -version = "0.1.3" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "version_check" @@ -1961,29 +1319,13 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" -dependencies = [ - "vcell", -] - [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -1994,168 +1336,155 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.82" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.82" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.82" +name = "winapi-util" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "winapi", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.82" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "web-sys" -version = "0.3.59" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "js-sys", - "wasm-bindgen", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] -name = "webpki" -version = "0.22.0" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "ring", - "untrusted", + "windows-targets", ] [[package]] -name = "webpki-roots" -version = "0.22.4" +name = "windows-targets" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "webpki", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] -name = "wide" -version = "0.7.4" +name = "windows_aarch64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3aba2d1dac31ac7cae82847ac5b8be822aee8f99a4e100f279605016b185c5f" -dependencies = [ - "bytemuck", - "safe_arch", -] +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] -name = "winapi" -version = "0.3.9" +name = "windows_aarch64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows_aarch64_msvc" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_i686_gnu" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows_i686_gnu" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" +name = "windows_i686_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] -name = "windows_i686_gnu" -version = "0.36.1" +name = "windows_i686_msvc" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] -name = "windows_i686_msvc" -version = "0.36.1" +name = "windows_x86_64_gnu" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml index 19aa074..8180e92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,2 @@ [workspace] -members = [ - "opentaws", - "taws_minimal", - "aviation_database", - "kd_tree", - "kd_tree_sort", -] - - -[patch.crates-io] -# TODO jump to normal uom once https://github.com/iliekturtles/uom/pull/309 lands -uom = { git = "https://github.com/wucke13/uom", branch = "fix-missing-libm" } \ No newline at end of file +members = ["opentaws", "taws_minimal"] diff --git a/aviation_database/Cargo.lock b/aviation_database/Cargo.lock deleted file mode 100644 index 4554032..0000000 --- a/aviation_database/Cargo.lock +++ /dev/null @@ -1,247 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" - -[[package]] -name = "array-init" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6945cc5422176fc5e602e590c2878d2c2acd9a4fe20a4baa7c28022521698ec6" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "aviation_database" -version = "0.1.0" -dependencies = [ - "anyhow", - "csv", - "opentaws", - "serde", - "uneval", - "uom", -] - -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "casey" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14" -dependencies = [ - "syn", -] - -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "opentaws" -version = "0.1.0" -source = "git+https://github.com/aeronautical-informatics/opentaws#d84201785d41fb734e931f143ee0f42c10706a0c" -dependencies = [ - "casey", - "lazy_static", - "ringbuffer", - "serde", - "uom", -] - -[[package]] -name = "proc-macro2" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - -[[package]] -name = "ringbuffer" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e49d3a791d79aa7683f8798b274073140865ffb9d65767ace44229d34299e3" -dependencies = [ - "array-init", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "syn" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "thiserror" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "uneval" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b95ceb1224b9d137ee19530b0d6f39c66d73098b50d41a4de4ccbf5e4f122" -dependencies = [ - "serde", - "thiserror", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "uom" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ee6bfd0a27bf614353809a035cf6880b74239ec6c5e39a7b2860ca16809137" -dependencies = [ - "num-traits", - "serde", - "typenum", -] diff --git a/aviation_database/Cargo.toml b/aviation_database/Cargo.toml deleted file mode 100644 index 3cec418..0000000 --- a/aviation_database/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "aviation_database" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -ordered-float = { version = "2.0", default-features = false } -uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } -kd_tree = { path = "../kd_tree" } - - -[build-dependencies] -anyhow = "1.0" -csv = "1.1" -proc-macro2 = "1.0" -quote = "1.0" -rayon = "1.5" -regex = "1.5" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -uneval = "0.2" -uom = { version = "0", default-features = false, features = [ "f64", "si", "libm" ] } -ureq = "2" -kd_tree_sort = { path = "../kd_tree_sort" } diff --git a/aviation_database/README.md b/aviation_database/README.md deleted file mode 100644 index 135f08b..0000000 --- a/aviation_database/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Todo - -In order for this to work, you need to download the airport database. Download -[this file](https://datahub.io/core/airport-codes/r/airport-codes.json) from -[datahub.io](https://datahub.io/core/airport-codes#data), and store it with the -name `airports.json` root of the `aviation_database` crate (where the -`build.rs` resides). diff --git a/aviation_database/build.rs b/aviation_database/build.rs deleted file mode 100644 index 7acf772..0000000 --- a/aviation_database/build.rs +++ /dev/null @@ -1,152 +0,0 @@ -use proc_macro2::{Literal, TokenStream}; -use quote::{quote, ToTokens}; -use rayon::prelude::*; -use serde::Deserialize; -use std::env; -use std::fs; -use std::io::BufRead; -use std::path::Path; -use std::process::Command; - -#[derive(Default, Debug, Clone, PartialEq, Deserialize)] -#[serde(rename_all = "snake_case")] -pub struct Airport { - pub continent: String, - pub coordinates: String, - pub elevation_ft: Option, - pub gps_code: Option, - pub iata_code: Option, - pub ident: String, - pub iso_country: String, - pub iso_region: String, - pub local_code: Option, - pub municipality: Option, - pub name: String, - #[serde(rename = "type")] - pub type_field: String, -} - -fn parse_airport_kd(airport: Airport) -> ([f64; 3], Airport) { - let mut coord = airport.coordinates.split(", "); - let lon: f64 = coord.next().map(|l| l.parse().ok()).flatten().unwrap(); - let lat: f64 = coord.next().map(|l| l.parse().ok()).flatten().unwrap(); - let alt: f64 = airport - .elevation_ft - .as_ref() - .map_or_else(|| Some(0.0), |e| e.parse().ok()) - .unwrap(); - - let x = alt * lat.cos() * lon.cos(); - let y = alt * lat.cos() * lon.sin(); - let z = alt * lat.sin(); - ([x, y, z], airport) -} - -impl ToTokens for Airport { - fn to_tokens(&self, tokens: &mut TokenStream) { - let mut coord = self.coordinates.split(", "); - let long: Option = coord.next().map(|l| l.parse().ok()).flatten(); - let lat: Option = coord.next().map(|l| l.parse().ok()).flatten(); - let alt: Option = self - .elevation_ft - .as_ref() - .map_or_else(|| Some(0.0), |e| e.parse().ok()); - let icao = format!( - "b\"{}\"", - self.ident - .chars() - .chain(std::iter::repeat('\0')) - .take(4) - .collect::() - ) - .parse::() - .unwrap(); - if long.is_none() || lat.is_none() || alt.is_none() { - return; - } - - tokens.extend(quote! { - AirportEntry { - icao: *#icao, - lat: #lat, - lon: #long, - alt: #alt, - } - }); - } -} - -fn main() { - let file_env = "AIRPORTS_JSON_FILE"; - let url_env = "AIRPORTS_JSON_URL"; - - let reader: Box = if let Ok(airports_file) = std::env::var(file_env) { - let f = std::fs::File::open(&airports_file) - .expect(&format!("file {} does not exist", airports_file)); - Box::new(std::io::BufReader::new(f)) - } else { - let airports_url = std::env::var(url_env) - .unwrap_or("https://datahub.io/core/airport-codes/r/airport-codes.json".into()); - let r = ureq::get(&airports_url) - .call() - .expect(&format!( - "unable to automatically download from {}", - airports_url - )) - .into_reader(); - Box::new(std::io::BufReader::new(r)) - }; - - let mut airports: Vec = serde_json::from_reader(reader).unwrap(); - - let num_airports = airports.len(); - let out_dir = env::var_os("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("airports.rs"); - let airports: Vec<([f64; 3], Airport)> = airports.par_drain(..).map(parse_airport_kd).collect(); - let airports = kd_tree_sort::sort(airports); - let airports: String = airports - .iter() - .fold(String::new(), |mut s, ([x, y, z], a)| { - //s.push_str("e!(#a).to_string()); - // Node - // new(val: [T; DIM], v: V) - s.push_str( - "e! { - Node::new( - [ #x, #y, #z ], - #a - ) - } - .to_string(), - ); - s.push(','); - s - }); - let max_level = (num_airports as f64).log2() as usize + 2; - fs::write( - &dest_path, - format!( - "pub const NODES: [Node; {}] = [ {} ];\ - pub const AIRPORTS: Tree:: = Tree::new( &NODES );", - num_airports, airports, max_level - ), - ) - .unwrap(); - - // format code - if let Err(e) = Command::new("rustfmt") - .arg(dest_path.as_os_str()) - .current_dir(&out_dir) - .status() - { - eprintln!("{}", e) - } - - println!( - "cargo:rerun-if-changed=build.rs - cargo:rerun-if-env-changed={} - cargo:rerun-if-env-changed={} - ", - url_env, file_env - ); -} diff --git a/aviation_database/src/consts.rs b/aviation_database/src/consts.rs deleted file mode 100644 index e14a0bf..0000000 --- a/aviation_database/src/consts.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::AirportEntry; -use kd_tree::{Node, Tree}; - -// Provides const AIRPORTS: &[AirportImpl] = ... -include!(concat!(env!("OUT_DIR"), "/airports.rs")); diff --git a/aviation_database/src/lib.rs b/aviation_database/src/lib.rs deleted file mode 100644 index 2f009ad..0000000 --- a/aviation_database/src/lib.rs +++ /dev/null @@ -1,216 +0,0 @@ -mod consts; -/// Contains a reference implementation from the -pub mod reference; - -// use opentaws::prelude::*; -use core::{ - fmt::Debug, - iter::{self, Iterator}, -}; -use ordered_float::OrderedFloat; -use uom::{ - num_traits::Pow, - si::{angle::degree, f64::*, length::foot, length::kilometer}, -}; - -use crate::consts::AIRPORTS; - -/// Describes the interface to a TerrainDatabase -/// -/// Each implementation of this type can be use as TerrainDatabase, providing elevation data for a -/// given `Position`. -pub trait TerrainDatabase { - /// Estimate elevation at a specific position - fn elevation_at(&self, position: Position) -> Length; -} - -/// Describes the interface of a AirportDatabase -/// -/// Each implementation of this type can be used as AirportDatabase, providing information about -/// `Airports` and `Runways` -pub trait AirportDatabase: Send + Sync + Debug { - type RunwayIterator: core::iter::Iterator - + From> - + Send - + Sync; - - /// Find the airport nearest to a given `Position` - fn nearest_airport(&self, position: &Position) -> Airport { - // For ~50000 Airports - // Linear Search took 7ms - // KD-Tree Search took 29µs - // CPU: Ryzen 5 5600X - - // Old slow Linear Search - //AIRPORTS.nodes - // .iter() - // .map(|n| Airport::from(n.payload())) - // .map(|a| (a.clone(), a.pos.relative_distance(position))) - // .reduce(|(c_a, c_d), (n_a, n_d)| match c_d.cmp(&n_d) { - // Ordering::Greater => (n_a, n_d), - // _ => (c_a, c_d), - // }) - // .unwrap() - // .0; - - // New fast KD-Tree Search - Airport::from(AIRPORTS.search(&position.cartesian_f64()).payload()) - } - - fn runways(&self, airport: &Airport) -> Self::RunwayIterator { - iter::empty().into() - } - /* - /// Find all Airports in a given perimeter - fn airports_in_perimeter(&self, position: P, perimeter: Length)-> - */ -} - -/// Describes a positon in three dimensional room -#[derive(Debug, Clone, PartialEq)] -pub struct Position { - pub lat: Angle, - pub lon: Angle, - pub alt: Length, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct Airport { - pub icao: [u8; 4], - pub pos: Position, -} - -impl Position { - const MEAN_EARTH_RADIUS_KILOMETER: f64 = 6371.001; - /// Converts the `Position` to cartesian coordinates. Nothing orientation is guaranteed, thus - /// this may only be used for relative distances etc. - fn cartesian(&self) -> [Length; 3] { - let x = self.alt * self.lat.cos() * self.lon.cos(); - let y = self.alt * self.lat.cos() * self.lon.sin(); - let z = self.alt * self.lat.sin(); - [x, y, z] - } - - /// Converts the `Position` to cartesian coordinates. Nothing orientation is guaranteed, thus - /// this may only be used for relative distances etc. - fn cartesian_f64(&self) -> [f64; 3] { - let x = self.alt.get::() - * self.lat.get::().cos() - * self.lon.get::().cos(); - let y = self.alt.get::() - * self.lat.get::().cos() - * self.lon.get::().sin(); - let z = self.alt.get::() * self.lat.get::().sin(); - [x, y, z] - } - - /// Get the relative distance of two points - /// - /// This can be used for comparing distances - fn relative_distance(&self, other: &Position) -> RelativeDistance { - RelativeDistance( - self.cartesian() - .iter() - .zip(&other.cartesian()) - .fold(OrderedFloat(0.0), |r, (a, b)| { - r + (a.value - b.value).pow(2) - }), - ) - } - - /// As we have two different altitudes, this function ignores the altitude of `other` and - /// calculates the great circle distance from `self` at the altitude of `self` to lat/lon of - /// `other` - /// - /// This implies, that this operation __is not commutatitve__. E.g. the following code will - /// panic: - /// - /// ``` - /// use aviation_database::Position; - /// use uom::si::{ - /// f64::{Angle, Length}, - /// angle::degree, - /// length::meter, - /// }; - /// - /// let p1 = Position{ - /// lat: Angle::new::(54.0), - /// lon: Angle::new::(10.0), - /// alt: Length::new::(1000.0), - /// }; - /// let p2 = Position{ - /// lat: Angle::new::(52.0), - /// lon: Angle::new::(8.0), - /// alt: Length::new::(1000.0), - /// }; - /// - /// let distance_delta = p1.great_circle(&p2) - p2.great_circle(&p1); - /// assert!(distance_delta.abs() < Length::new::(1.0)); - /// ``` - #[allow(non_snake_case)] - pub fn great_circle(&self, other: &Position) -> Length { - // borrows formula from https://en.wikipedia.org/wiki/Great-circle_distance - let λ1 = self.lon; - let λ2 = other.lon; - let Δλ = λ1 - λ2; - let Φ1 = self.lat; - let Φ2 = other.lat; - - let a = Φ2.cos() * Δλ.sin(); - let b = Φ1.cos() * Φ2.sin() - Φ1.sin() * Φ2.cos() * Δλ.cos(); - let c = Φ1.sin() * Φ2.sin() + Φ1.cos() * Φ2.cos() * Δλ.cos(); - - let radius = Length::new::(Self::MEAN_EARTH_RADIUS_KILOMETER) + self.alt; - - radius * ((a * a + b * b) / c).sqrt().atan() - } -} - -/// Distance between two points -#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] -pub struct RelativeDistance(OrderedFloat); - -pub struct AirportEntry { - pub icao: [u8; 4], - pub lat: f64, - pub lon: f64, - pub alt: f64, -} - -impl From<&AirportEntry> for Position { - fn from(entry: &AirportEntry) -> Self { - Self { - lat: Angle::new::(entry.lat), - lon: Angle::new::(entry.lon), - alt: Length::new::(entry.alt), - } - } -} - -impl From<&AirportEntry> for Airport { - fn from(a: &AirportEntry) -> Self { - Airport { - icao: a.icao, - pos: a.into(), - } - } -} - -impl AsRef for Airport { - fn as_ref(&self) -> &Position { - &self.pos - } -} - -impl From for Position { - fn from(entry: AirportEntry) -> Self { - Self { - lat: Angle::new::(entry.lat), - lon: Angle::new::(entry.lon), - alt: Length::new::(entry.alt), - } - } -} - -#[derive(Clone, Debug)] -pub struct Runway(); diff --git a/aviation_database/src/reference.rs b/aviation_database/src/reference.rs deleted file mode 100644 index d518e47..0000000 --- a/aviation_database/src/reference.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::{AirportDatabase, Runway}; - -#[derive(Debug, Default)] -pub struct AirportDatabaseImpl; - -impl AirportDatabase for AirportDatabaseImpl { - type RunwayIterator = core::iter::Empty; -} diff --git a/kd_tree/Cargo.toml b/kd_tree/Cargo.toml deleted file mode 100644 index d5ebf61..0000000 --- a/kd_tree/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "kd_tree" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] - -[dependencies.num] -version = "0.4" -default-features = false \ No newline at end of file diff --git a/kd_tree/README.md b/kd_tree/README.md deleted file mode 100644 index 40d6dc6..0000000 --- a/kd_tree/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# KD-Tree implementation - -Implements only functions required for searching an already initialized KD-Tree. -Because of this, this crate is no_std compatible - -Code for building the KD-Tree can be found in `kd_tree_sort`. -`kd_tree_sort` is not no_std compatible which is why these two crates were seperated. -A fuzzy tester as well as a benchmark verifying this implementation can be found in `kd_tree_sort`. \ No newline at end of file diff --git a/kd_tree/src/lib.rs b/kd_tree/src/lib.rs deleted file mode 100644 index 28c402a..0000000 --- a/kd_tree/src/lib.rs +++ /dev/null @@ -1,252 +0,0 @@ -#![no_std] -#![allow(clippy::too_many_arguments)] -use core::cmp::Ordering; -use core::fmt::Debug; -use num::traits::Num; - -pub struct Tree<'a, T, V, const DIM: usize, const MAX_LEVEL: usize> { - pub nodes: &'a [Node], -} - -impl Tree<'static, T, V, DIM, MAX_LEVEL> { - pub const fn new(nodes: &'static [Node]) -> Tree<'static, T, V, DIM, MAX_LEVEL> { - Tree { nodes } - } -} - -impl<'a, T: PartialOrd + Num + Copy + Debug, V, const DIM: usize, const MAX_LEVEL: usize> - Tree<'a, T, V, DIM, MAX_LEVEL> -{ - pub fn search(&self, point: &[T; DIM]) -> &Node { - let mut node: &Node = self - .nodes - .first() - .expect("This can not fail, expect if the Tree got no nodes: SIZE == 0"); - let mut index = 0usize; - let mut level = 0usize; - // Store which child nodes where visited for the Node on the index/level and if it was - // already compared - let mut visited: [(Visited, bool); MAX_LEVEL] = [(Visited::None, false); MAX_LEVEL]; - //Initialise best node/distance with root node - let mut best_distance: T = euclid(&node.val, point); - let mut best_node: &Node = node; - - loop { - // Get to leaf based on comparison of only a single dimension per level - self.search_down(point, &mut node, &mut index, &mut level, &mut visited); - - // Go up until we either reach the top or we go down by one - // Should we go down by one, we will need to go to the best fit leaf of the current - // subtree - self.search_up( - point, - &mut node, - &mut index, - &mut level, - &mut visited, - &mut best_distance, - &mut best_node, - ); - - // Should we have reached level 0, we are finished - // as search_up should go down by one should we still need to search a subtree - if level == 0 { - break; - } - } - - best_node - } - - fn search_down( - &'a self, - point: &[T; DIM], - node: &mut &'a Node, - index: &mut usize, - level: &mut usize, - visited: &mut [(Visited, bool); MAX_LEVEL], - ) { - //Get to leaf node - loop { - //Reset Visited and calculated distance for current level - visited[*level] = (Visited::None, false); - - let dim = *level % DIM; - - //If the left node is not reachable we are at a leaf node - if left(index) >= self.nodes.len() { - //Set visited for this level to ALL because there are no more child nodes - visited[*level].0 = Visited::All; - return; - } - //Decide where to go - *index = match point[dim].partial_cmp(&node.val[dim]) { - Some(Ordering::Equal) | Some(Ordering::Less) => left(index), - Some(Ordering::Greater) => right(index), - _ => panic!(), - }; - - // If the index is to big we choose the right node - // Make sure it exists, if not go to the left node instead - if *index >= self.nodes.len() { - *index -= 1; - } - - // Set next node - *node = self.nodes.get(*index).unwrap(); - - // Increase level for next node - *level += 1; - } - } - - fn search_up( - &'a self, - point: &[T; DIM], - node: &mut &'a Node, - index: &mut usize, - level: &mut usize, - visited: &mut [(Visited, bool); MAX_LEVEL], - best_distance: &mut T, - best_node: &mut &'a Node, - ) { - loop { - let dim = *level % DIM; - - // Check if current node is a closer node - if !visited[*level].1 { - let candidate: T = euclid(&node.val, point); - if candidate < *best_distance { - *best_distance = candidate; - *best_node = node; - } - visited[*level].1 = true; - } - - // Determine where to go? Up, BottomLeft or BottomRight - let dir: Direction = match visited[*level].0 { - Visited::All => Direction::Up, - Visited::Left => { - // Check if we even can go right - // and if its even possible for the right side to be nearer - let single_distance = point[dim] - node.val[dim]; - let single_distance = single_distance * single_distance; - if right(index) < self.nodes.len() && single_distance < *best_distance { - Direction::Right - } else { - Direction::Up - } - } - Visited::Right => { - // Check if we even can go left - // and if its even possible for the left side to be nearer - let single_distance = point[dim] - node.val[dim]; - let single_distance = single_distance * single_distance; - if left(index) < self.nodes.len() && single_distance < *best_distance { - Direction::Left - } else { - Direction::Up - } - } - _ => panic!("Unexpected state"), - }; - - match dir { - Direction::Up => { - //Stop if we are at level 0 - if *level == 0 { - return; - } - - // Move up - let parent_index = parent(index); - *level -= 1; - // But update the visited status of the parent first - // This way we know which children were already visited - match visited[*level].0 { - Visited::Left | Visited::Right => visited[*level].0 = Visited::All, - _ => { - if left(&parent_index) == *index { - visited[*level].0 = Visited::Left; - } else { - visited[*level].0 = Visited::Right; - } - } - } - *index = parent_index; - *node = self.nodes.get(*index).unwrap(); - } - Direction::Left => { - *level += 1; - visited[*level].0 = Visited::None; - *index = left(index); - *node = self.nodes.get(*index).unwrap(); - return; - } - Direction::Right => { - *level += 1; - visited[*level].0 = Visited::None; - *index = right(index); - *node = self.nodes.get(*index).unwrap(); - return; - } - } - } - } -} - -#[derive(Copy, Clone, Debug)] -enum Visited { - None, - Left, - Right, - All, -} - -enum Direction { - Up, - Left, - Right, -} - -pub fn parent(cur_index: &usize) -> usize { - (cur_index + 1) / 2 - 1 -} - -pub fn left(cur_index: &usize) -> usize { - (cur_index + 1) * 2 - 1 -} - -pub fn right(cur_index: &usize) -> usize { - (cur_index + 1) * 2 -} - -#[derive(Debug)] -pub struct Node { - val: [T; DIM], - v: V, -} - -impl Node { - pub fn val(&self) -> &[T; DIM] { - &self.val - } - - pub const fn new(val: [T; DIM], v: V) -> Node { - Node { val, v } - } - - pub fn payload(&self) -> &V { - &self.v - } -} - -pub fn euclid(left: &[T; SIZE], right: &[T; SIZE]) -> T -where - T: Num + Copy + Debug, -{ - left.iter() - .zip(right.iter()) - .map(|(x, y)| ((*x) - (*y)) * ((*x) - (*y))) - .fold(T::zero(), ::core::ops::Add::add) -} diff --git a/kd_tree_sort/Cargo.toml b/kd_tree_sort/Cargo.toml deleted file mode 100644 index 9dbb41c..0000000 --- a/kd_tree_sort/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "kd_tree_sort" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -kd_tree = { path = "../kd_tree" } -rayon = "1.5" - -[dev-dependencies] -rand = "0.8" -rand_pcg = "*" -itertools = "0.10" -criterion = "0.3" - -[lib] -bench = false - -[[bench]] -name = "search" -harness = false diff --git a/kd_tree_sort/README.md b/kd_tree_sort/README.md deleted file mode 100644 index 8c28be9..0000000 --- a/kd_tree_sort/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# KD-Tree sort implemention - -Implements a non-no_std compatible sort function for usage with the `kd_tree` crate. - -## Benchmark -For benchmarking purposed, criterion.rs was used, comparing our kd-tree against a basic linear_search. - -Run: `cargo bench` in this directory. - -## Fuzzy Test -The implemented fuzzy test uses `cargo fuzz` -Install it before running the fuzzy test (a nightly toolchain may be required). - -It compares the result of the linear search algorithm against the result of the kd-tree search. -The fuzzy test input is filtering out `Inf` and `NaN` values since our kd-tree is -supposed to find the nearest-neighbor on valid input data only. - -For starting the fuzzy test run: `cargo fuzz run kd_tree_search --sanitizer=leak` in this directory. -*Note: the fuzzy test will run until it finds an error* \ No newline at end of file diff --git a/kd_tree_sort/benches/search.rs b/kd_tree_sort/benches/search.rs deleted file mode 100644 index 68f8883..0000000 --- a/kd_tree_sort/benches/search.rs +++ /dev/null @@ -1,65 +0,0 @@ -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; -use kd_tree::{euclid, Node, Tree}; -use kd_tree_sort::sort; -use rand::Rng; -use std::time::Duration; - -type Prng = rand_pcg::Mcg128Xsl64; - -fn linear_search(nodes: &[Node], point: &[f64; 3]) -> f64 { - nodes - .iter() - .map(|a| euclid(point, a.val())) - .min_by(|a, b| a.partial_cmp(b).unwrap()) - .unwrap() -} - -fn generate_values(len: usize, rng: &mut Prng) -> Vec<([f64; 3], i32)> { - (0..len).map(|_| (generate_point(rng), 0)).collect() -} - -fn generate_sorted(len: usize, rng: &mut Prng) -> Vec> { - let sorted = sort(generate_values(len, rng)); - sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect() -} - -fn generate_point(rng: &mut Prng) -> [f64; 3] { - [rng.gen(), rng.gen(), rng.gen()] -} - -pub fn search(c: &mut Criterion) { - let mut rng = Prng::new(0xcafef00dd15ea5e5); - - const START_LEN: usize = 1000; - const END_LEN: usize = 64001; - - const MAX_LEVEL: usize = 16; - - let mut group = c.benchmark_group("Search"); - group.warm_up_time(Duration::from_millis(50)); - group.measurement_time(Duration::from_secs(1)); - - for len in (START_LEN..END_LEN).step_by(1000) { - let nodes = generate_sorted(len, &mut rng); - let tree = Tree:: { - nodes: nodes.as_slice(), - }; - group.bench_with_input(BenchmarkId::new("KD Tree", len), &tree, |b, t| { - b.iter_batched( - || generate_point(&mut rng), - |p| t.search(&p), - BatchSize::SmallInput, - ) - }); - group.bench_with_input(BenchmarkId::new("Linear", len), &nodes, |b, n| { - b.iter_batched( - || generate_point(&mut rng), - |p| linear_search(n, &p), - BatchSize::SmallInput, - ) - }); - } -} - -criterion_group!(benches, search); -criterion_main!(benches); diff --git a/kd_tree_sort/fuzz/.gitignore b/kd_tree_sort/fuzz/.gitignore deleted file mode 100644 index a092511..0000000 --- a/kd_tree_sort/fuzz/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target -corpus -artifacts diff --git a/kd_tree_sort/fuzz/Cargo.lock b/kd_tree_sort/fuzz/Cargo.lock deleted file mode 100644 index 1ed5d69..0000000 --- a/kd_tree_sort/fuzz/Cargo.lock +++ /dev/null @@ -1,303 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "arbitrary" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "cc" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "derive_arbitrary" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "kd_tree" -version = "0.1.0" -dependencies = [ - "num", -] - -[[package]] -name = "kd_tree_sort" -version = "0.1.0" -dependencies = [ - "kd_tree", - "rayon", -] - -[[package]] -name = "kd_tree_sort-fuzz" -version = "0.0.0" -dependencies = [ - "arbitrary", - "kd_tree", - "kd_tree_sort", - "libfuzzer-sys", - "rayon", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" - -[[package]] -name = "libfuzzer-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" -dependencies = [ - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "proc-macro2" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "syn" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/kd_tree_sort/fuzz/Cargo.toml b/kd_tree_sort/fuzz/Cargo.toml deleted file mode 100644 index 4f84664..0000000 --- a/kd_tree_sort/fuzz/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "kd_tree_sort-fuzz" -version = "0.0.0" -publish = false -edition = "2018" - -[package.metadata] -cargo-fuzz = true - -[dependencies] -libfuzzer-sys = "0.4" -arbitrary = { version = "1", features = ["derive"] } -rayon = "1.5" - -[dependencies.kd_tree_sort] -path = ".." -[dependencies.kd_tree] -path = "../../kd_tree" - -# Prevent this from interfering with workspaces -[workspace] -members = ["."] - -[[bin]] -name = "kd_tree_search" -path = "fuzz_targets/kd_tree_search.rs" -test = false -doc = false diff --git a/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs b/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs deleted file mode 100644 index 9fc928b..0000000 --- a/kd_tree_sort/fuzz/fuzz_targets/kd_tree_search.rs +++ /dev/null @@ -1,55 +0,0 @@ -#![no_main] -use kd_tree::{euclid, Node, Tree}; -use kd_tree_sort::sort; -use libfuzzer_sys::fuzz_target; -use rayon::prelude::*; - -#[derive(Clone, Debug, arbitrary::Arbitrary)] -struct ArbitraryPoint { - pos: [f64; 3], - p: i32, -} - -unsafe impl Sync for ArbitraryPoint{} -unsafe impl Send for ArbitraryPoint{} - -fn linear_search(nodes: &[Node], point: &[f64; 3]) -> f64 { - nodes - .iter() - .map(|a| euclid(point, a.val())) - .min_by(|a, b| a.partial_cmp(b).unwrap()) - .unwrap() -} - -const MAX_LEVEL: usize = 16; - -fuzz_target!(|data: Vec| { - let mut data = data; - let mut data: Vec<_> = data - .drain(..) - .filter(|p| p.pos[0].is_finite() && p.pos[1].is_finite() && p.pos[2].is_finite()) - .take((2usize.pow(MAX_LEVEL as u32) - 1) * 2) - .par_bridge() - .map(|p| (p.pos, p.p)) - .collect(); - - if data.len() < 2 { - // Dont fuzzy test less than two elements - return; - } - - let search_data: Vec<_> = data.split_off(data.len() / 2); - - let sorted = sort(data); - let sorted: Vec<_> = sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect(); - let tree = Tree:: { - nodes: sorted.as_slice(), - }; - - search_data.par_iter().for_each(|(p, _)| { - assert_eq!( - euclid(tree.search(&p).val(), &p), - linear_search(&sorted, &p) - ) - }); -}); diff --git a/kd_tree_sort/src/lib.rs b/kd_tree_sort/src/lib.rs deleted file mode 100644 index 50a553e..0000000 --- a/kd_tree_sort/src/lib.rs +++ /dev/null @@ -1,205 +0,0 @@ -use kd_tree::{left, right}; -use rayon::prelude::*; - -pub fn sort< - T: Sized + PartialOrd + PartialEq + core::fmt::Debug + Send, - V: Sized + Send, - const DIM: usize, ->( - mut values: Vec<([T; DIM], V)>, -) -> Vec<([T; DIM], V)> { - //Add variable for final index - let mut values: Vec<_> = values.par_drain(..).map(|(a, b)| (a, b, 0usize)).collect(); - //Call Recursive Sort function - rec_sort(&mut values, 0, 0); - - //Apply final index by sorting by this index - values.par_sort_by(|(_, _, a), (_, _, b)| { - // Verify inequality of indices - assert_ne!(a, b); - a.cmp(b) - }); - - //Remove index and return - values.par_drain(..).map(|(a, b, _)| (a, b)).collect() -} - -fn rec_sort( - values: &mut [([T; DIM], V, usize)], - dim: usize, - index: usize, -) { - //Check dimension - let dim = dim % DIM; - - // Sort by current dimension - values.par_sort_by(|(a, _, _), (b, _, _)| a[dim].partial_cmp(&b[dim]).unwrap()); - - if values.len() == 1 { - values[0].2 = index; - return; - } else if values.len() == 2 { - values[1].2 = index; - rec_sort(&mut values[..1], dim + 1, left(&index)); - return; - } - let len = values.len(); - let lv = (len as f64).log2() as usize; - let last_line_len = len - 2usize.pow(lv as u32) + 1; - let mid = 2usize.pow(lv as u32) / 2 - 1; - let mid = if last_line_len < 2usize.pow(lv as u32) / 2 { - mid + last_line_len - } else { - mid + 2usize.pow(lv as u32) / 2 - }; - - let (left_slice, rest) = values.split_at_mut(mid); - let (mid, right_slice) = rest.split_at_mut(1); - - mid.get_mut(0).unwrap().2 = index; - // 3 times faster for 50000 elements - [(left_slice, left(&index)), (right_slice, right(&index))] - .into_par_iter() - .for_each(|(s, i)| rec_sort(s, dim + 1, i)); -} - -#[cfg(test)] -mod tests { - #![allow(clippy::float_cmp)] - #![allow(deprecated)] - use crate::sort; - use kd_tree::{euclid, Node, Tree}; - use rand::Rng; - use std::ops::AddAssign; - use std::time::{Duration, Instant}; - type Prng = rand_pcg::Mcg128Xsl64; - - #[test] - fn fixed_test() { - let test = sort(vec![ - ([5, 4], 0), - ([2, 3], 1), - ([8, 1], 2), - ([9, 6], 3), - ([7, 2], 4), - ([4, 7], 5), - ]); - let correct = [ - ([7, 2], 4), - ([5, 4], 0), - ([9, 6], 3), - ([2, 3], 1), - ([4, 7], 5), - ([8, 1], 2), - ]; - - assert_eq!(test, correct) - } - - #[test] - fn search() { - let sorted = sort(vec![ - ([5, 4], 0), - ([2, 3], 1), - ([8, 1], 2), - ([9, 6], 3), - ([7, 2], 4), - ([4, 7], 5), - ]); - - let nodes = sorted - .iter() - .map(|(p, v)| Node::new(*p, *v)) - .collect::>(); - //T, V, SIZE, DIM, MAX_LEVEL - let tree = Tree:: { - nodes: nodes.as_slice(), - }; - - assert_eq!(tree.search(&[5, 3]).val(), &[5, 4]); - assert_eq!(tree.search(&[9, 7]).val(), &[9, 6]); - assert_eq!(tree.search(&[3, 9]).val(), &[4, 7]); - assert_eq!(tree.search(&[3, 0]).val(), &[2, 3]); - } - - #[test] - fn random_search() { - let mut rng = Prng::new(0xcafef00dd15ea5e5); - let mut duration_linear_min = Duration::from_secs(9999); - let mut duration_linear = Duration::from_secs(0); - let mut duration_linear_max = Duration::from_secs(0); - let mut duration_tree_min = Duration::from_secs(9999); - let mut duration_tree = Duration::from_secs(0); - let mut duration_tree_max = Duration::from_secs(0); - - let (iterations, searches) = if cfg!(debug_assertions) { - (10, 500) - } else { - (100, 500) - }; - - #[cfg(debug_assertions)] - const TREE_SIZE: usize = 5000; - #[cfg(not(debug_assertions))] - const TREE_SIZE: usize = 60000; - - #[cfg(debug_assertions)] - const MAX_LEVEL: usize = 13; - #[cfg(not(debug_assertions))] - const MAX_LEVEL: usize = 16; - - for _ in 0..iterations { - let values: Vec<([f64; 3], i32)> = (0..TREE_SIZE) - .map(|_| ([rng.gen(), rng.gen(), rng.gen()], 0)) - .collect(); - let sorted = sort(values.clone()); - let nodes: Vec<_> = sorted.iter().map(|(p, v)| Node::new(*p, *v)).collect(); - let tree = Tree:: { - nodes: nodes.as_slice(), - }; - - let search_points: Vec<[f64; 3]> = - std::iter::repeat_with(|| [rng.gen(), rng.gen(), rng.gen()]) - .take(searches) - .collect(); - for point in search_points { - let now = Instant::now(); - let closest: f64 = values - .iter() - .map(|a| euclid(&point, &a.0)) - .min_by(|a, b| a.partial_cmp(b).unwrap()) - .unwrap(); - let lin_dur = now.elapsed(); - let now = Instant::now(); - let closest_node = tree.search(&point); - let tree_dur = now.elapsed(); - assert_eq!(closest, euclid(closest_node.val(), &point),); - - duration_linear.add_assign(lin_dur); - if lin_dur < duration_linear_min { - duration_linear_min = lin_dur - } else if lin_dur > duration_linear_max { - duration_linear_max = lin_dur - } - - duration_tree.add_assign(tree_dur); - if tree_dur < duration_tree_min { - duration_tree_min = tree_dur - } else if tree_dur > duration_tree_max { - duration_tree_max = tree_dur - } - } - } - - println!("Duration Linear Search: {:?}", duration_linear); - println!("Duration KD Tree Search: {:?}", duration_tree); - println!( - "{:.2}x increase in performance", - duration_linear.as_micros() as f64 / duration_tree.as_micros() as f64 - ); - println!("\nFastest KD Tree Search: {:?}", duration_tree_min); - println!("Slowest KD Tree Search: {:?}", duration_tree_max); - println!("Fastest Linear Search: {:?}", duration_linear_min); - println!("Slowest Linear Search: {:?}", duration_linear_max); - } -} diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 508f6c4..daa51c5 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -22,17 +22,15 @@ is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS maintenance = { status = "actively-developed" } [features] -default = ["use-serde"] -use-serde = ["uom/use_serde"] [dependencies] -aviation_database = { path = "../aviation_database" } -lazy_static = { version = "1", features = ["spin_no_std"] } +lazy_static = { version = "1", default-features = false, features = [ + "spin_no_std", +] } heapless = "0.7.16" hash32 = "0.2.1" -nalgebra = { version = "0.31.1", features = ["libm"] } - -uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } -ringbuffer = "0.8" -serde = { version = "1.0", default-features = false, features = ["derive"] } -serde_arrays = "*" # Serde const generic "workaround" +nalgebra = { version = "0.32.2", default-features = false, features = ["libm"] } +uom = { git = "https://github.com/moritz-meier/uom.git", branch = "fix-missing-libm", default-features = false, features = [ + "f64", + "si", +] } diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 4885658..02267ac 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -6,17 +6,15 @@ use core::{ use lazy_static::lazy_static; -use crate::prelude::*; -use ::uom::fmt::DisplayStyle; -use ::uom::si::ratio::ratio; +use crate::prelude::{uom::fmt::DisplayStyle, *}; // ToDo: turn into consts when uom supports const new lazy_static! { - static ref ZERO_REVOLUTION: Angle = Angle::new::(0.0); - static ref QUARTER_REVOLUTION: Angle = Angle::new::(0.25); - static ref HALF_REVOLUTION: Angle = Angle::new::(0.5); - static ref ONE_REVOLUTION: Angle = Angle::new::(1.0); - static ref ZERO_LENGTH: Length = Length::new::(0.0); + static ref ZERO_REVOLUTION: Angle = Angle::new::(0.0); + static ref QUARTER_REVOLUTION: Angle = Angle::new::(0.25); + static ref HALF_REVOLUTION: Angle = Angle::new::(0.5); + static ref ONE_REVOLUTION: Angle = Angle::new::(1.0); + static ref ZERO_LENGTH: Length = Length::new::(0.0); } /// Marker for normalized AircraftStates @@ -33,7 +31,6 @@ pub type NormalizedAircraftState = AircraftState; /// Represents the current state of an aircraft #[derive(Clone, Debug, Default)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] pub struct AircraftState { /// Time when this aircraft state was emitted timestamp: Time, @@ -243,7 +240,11 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { - let quadrant = ((lat.abs() / *QUARTER_REVOLUTION).get::().floor() as i64) % 4; + use ::uom::num_traits::Float; + let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) + .get::() + .floor() as i64) + % 4; let pole = if lat > *ZERO_REVOLUTION { *QUARTER_REVOLUTION @@ -302,11 +303,11 @@ impl From for AircraftState { impl Display for AircraftState { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let s = Time::format_args(time_second, DisplayStyle::Abbreviation); - let ft = Length::format_args(foot, DisplayStyle::Abbreviation); - let deg = Angle::format_args(degree, DisplayStyle::Abbreviation); - let fpm = Velocity::format_args(foot_per_minute, DisplayStyle::Abbreviation); - let kt = Velocity::format_args(knot, DisplayStyle::Abbreviation); + let s = Time::format_args(time::second, DisplayStyle::Abbreviation); + let ft = Length::format_args(length::foot, DisplayStyle::Abbreviation); + let deg = Angle::format_args(angle::degree, DisplayStyle::Abbreviation); + let fpm = Velocity::format_args(velocity::foot_per_minute, DisplayStyle::Abbreviation); + let kt = Velocity::format_args(velocity::knot, DisplayStyle::Abbreviation); write!( f, @@ -337,7 +338,6 @@ AircrafState: {{ /// Represents a flight segment #[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] pub enum FlightSegment { /// The aircraft is in cruise flight situation Cruise, @@ -387,13 +387,13 @@ mod test { #[test] fn $name() { let mut state = AircraftState::new(); - *state.position_latitude_mut() = Angle::new::($pos.0); - *state.position_longitude_mut() = Angle::new::($pos.1); + *state.position_latitude_mut() = Angle::new::($pos.0); + *state.position_longitude_mut() = Angle::new::($pos.1); let norm_state = state.normalize(); - assert!(angle_approx_eq(norm_state.position_latitude(), Angle::new::($expected.0))); - assert!(angle_approx_eq(norm_state.position_longitude(), Angle::new::($expected.1))); + assert!(angle_approx_eq(norm_state.position_latitude(), Angle::new::($expected.0))); + assert!(angle_approx_eq(norm_state.position_longitude(), Angle::new::($expected.1))); })* }; } @@ -434,26 +434,26 @@ mod test { #[test] fn test_clamp_pos_alt_gnd() { let mut state = AircraftState::new(); - *state.altitude_ground_mut() = Length::new::(1000.0); + *state.altitude_ground_mut() = Length::new::(1000.0); let norm_state = state.normalize(); assert!(length_approx_eq( norm_state.altitude_ground(), - Length::new::(1000.0) + Length::new::(1000.0) )) } #[test] fn test_clamp_neg_alt_gnd() { let mut state = AircraftState::new(); - *state.altitude_ground_mut() = Length::new::(-1000.0); + *state.altitude_ground_mut() = Length::new::(-1000.0); let norm_state = state.normalize(); assert!(length_approx_eq( norm_state.altitude_ground(), - Length::new::(0.0) + Length::new::(0.0) )) } @@ -462,11 +462,11 @@ mod test { #[test] fn $name() { let mut state = AircraftState::new(); - *state.heading_mut() = Angle::new::($hdg); + *state.heading_mut() = Angle::new::($hdg); let norm_state = state.normalize(); - assert!(angle_approx_eq(norm_state.heading(), Angle::new::($expected))); + assert!(angle_approx_eq(norm_state.heading(), Angle::new::($expected))); })* }; } @@ -491,11 +491,11 @@ mod test { #[test] fn $name() { let mut state = AircraftState::new(); - *state.track_mut() = Angle::new::($trk); + *state.track_mut() = Angle::new::($trk); let norm_state = state.normalize(); - assert!(angle_approx_eq(norm_state.track(), Angle::new::($expected))); + assert!(angle_approx_eq(norm_state.track(), Angle::new::($expected))); })* }; } @@ -516,10 +516,10 @@ mod test { } fn angle_approx_eq(value: Angle, target: Angle) -> bool { - (target - value).abs() < Angle::new::(EPS) + (target - value).abs() < Angle::new::(EPS) } fn length_approx_eq(value: Length, target: Length) -> bool { - (target - value).abs() < Length::new::(EPS) + (target - value).abs() < Length::new::(EPS) } } diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 0293ca7..19e86d2 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,8 +1,8 @@ -use crate::prelude::*; - -pub use hash32::{Hash, Hasher}; +use hash32::Hash; use heapless::FnvIndexMap; +use crate::prelude::*; + /// TAWS Alert levels #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlertLevel { diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index 438f4dc..65da407 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -8,8 +8,8 @@ use core::{fmt::Display, slice::Iter}; use hash32::{Hash, Hasher}; use crate::alerts::Alert; -use crate::prelude::*; +use crate::prelude::*; pub use {ffac::*, /*flta::*,*/ mode1::*, mode3::*, pda::*}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -38,7 +38,7 @@ impl TawsAlertSource for ClassC_Source { const NUM_ALERT_SOURCES: usize = 5; const ALERT_SOURCES: &'static [Self] = &[ ClassC_Source::Ffac, - //ClassC_Source::Flta, + //ClassC_Source::Flta, ClassC_Source::Mode1, ClassC_Source::Mode3, ClassC_Source::Pda, @@ -94,7 +94,7 @@ impl TawsFunctionalities for ClassC { ) -> &dyn TawsFunctionality { match alert_src { ClassC_Source::Ffac => &self.ffac, - //ClassC_Source::Flta => &self.flta, + //ClassC_Source::Flta => &self.flta, ClassC_Source::Mode1 => &self.mode1, ClassC_Source::Mode3 => &self.mode3, ClassC_Source::Pda => &self.pda, @@ -107,7 +107,7 @@ impl TawsFunctionalities for ClassC { ) -> &mut dyn TawsFunctionality { match alert_src { ClassC_Source::Ffac => &mut self.ffac, - //ClassC_Source::Flta => &mut self.flta, + //ClassC_Source::Flta => &mut self.flta, ClassC_Source::Mode1 => &mut self.mode1, ClassC_Source::Mode3 => &mut self.mode3, ClassC_Source::Pda => &mut self.pda, @@ -139,7 +139,6 @@ impl TawsError for ClassCError {} impl From for &dyn TawsError { fn from(err: ClassCError) -> Self { match err { - ClassCError::InvalidAircraftState => &ClassCError::InvalidAircraftState, } } diff --git a/opentaws/src/class_c/ffac.rs b/opentaws/src/class_c/ffac.rs index ec5196d..e7d1e2a 100644 --- a/opentaws/src/class_c/ffac.rs +++ b/opentaws/src/class_c/ffac.rs @@ -1,9 +1,9 @@ -use crate::{alerts::*, prelude::*}; +use lazy_static::lazy_static; -use super::{ClassCError, ClassC_Source}; +use crate::alerts::*; +use crate::prelude::{num_traits::Zero, *}; -use ::uom::num_traits::Zero; -use lazy_static::lazy_static; +use super::{ClassCError, ClassC_Source}; #[derive(Clone, Debug)] pub struct Ffac { @@ -83,5 +83,5 @@ impl TawsFunctionality for Ffac { } lazy_static! { - static ref FIVE_HUNDRED: Length = Length::new::(500.0); //ToDo make const + static ref FIVE_HUNDRED: Length = Length::new::(500.0); //ToDo make const } diff --git a/opentaws/src/class_c/mode1.rs b/opentaws/src/class_c/mode1.rs index bcb2b2f..a2fa582 100644 --- a/opentaws/src/class_c/mode1.rs +++ b/opentaws/src/class_c/mode1.rs @@ -1,9 +1,10 @@ -use crate::{alerts::*, envelope::*, prelude::*}; +use crate::prelude::*; +use crate::{alerts::*, envelope::*}; use super::ClassC_Source; use lazy_static::lazy_static; -use nalgebra::{Vector, Vector2}; +use nalgebra::Vector2; #[derive(Clone, Debug)] pub struct Mode1 { @@ -57,8 +58,8 @@ impl TawsFunctionality for Mode1 { &mut self, state: &NormalizedAircraftState, ) -> Result, &'static dyn TawsError> { - let rod = -state.climb_rate().get::(); - let altitude_gnd = state.altitude_ground().get::(); + let rod = -state.climb_rate().get::(); + let altitude_gnd = state.altitude_ground().get::(); if !LIMITS.contains(Vector2::new(rod, altitude_gnd)) { let _x = 437; diff --git a/opentaws/src/class_c/mode3.rs b/opentaws/src/class_c/mode3.rs index 663f8a9..0b3606d 100644 --- a/opentaws/src/class_c/mode3.rs +++ b/opentaws/src/class_c/mode3.rs @@ -1,12 +1,10 @@ -use crate::{alerts::*, envelope::*, prelude::*}; - -use super::ClassC_Source; - -use ::uom::num_traits::Zero; use lazy_static::lazy_static; use nalgebra::Vector2; -use super::ClassCError; +use crate::prelude::{num_traits::Zero, *}; +use crate::{alerts::*, envelope::*}; + +use super::{ClassCError, ClassC_Source}; #[derive(Clone, Debug)] pub struct Mode3 { @@ -77,9 +75,10 @@ impl TawsFunctionality for Mode3 { self.max_altitude_ground = Length::max(self.max_altitude_ground, state.altitude_ground()); - let altitude_loss = (self.max_altitude_ground - state.altitude_ground()).get::(); - let rod = -state.climb_rate().get::(); - let altitude_gnd = state.altitude_ground().get::(); + let altitude_loss = + (self.max_altitude_ground - state.altitude_ground()).get::(); + let rod = -state.climb_rate().get::(); + let altitude_gnd = state.altitude_ground().get::(); let method1_res = METHODE_1_CAUTION_ENVELOPE.contains(rod, altitude_gnd)?; let method2_res = METHODE_2_CAUTION_ENVELOPE.contains(altitude_loss, altitude_gnd)?; @@ -108,7 +107,7 @@ lazy_static! { Vector2::new(330_000.0, 330_000.0) ); - // Envelopes enlarged by d=10, to prevent floating pointing problems. + // Envelopes enlarged by d=10, to prevent floating pointing problems. static ref METHODE_1_CAUTION_ENVELOPE: Envelope::<4> = Envelope::new( *METHOD1_LIMITS, &[ diff --git a/opentaws/src/class_c/pda.rs b/opentaws/src/class_c/pda.rs index 5b34e00..ad660fc 100644 --- a/opentaws/src/class_c/pda.rs +++ b/opentaws/src/class_c/pda.rs @@ -1,4 +1,5 @@ -use crate::{alerts::*, envelope::*, prelude::*}; +use crate::prelude::*; +use crate::{alerts::*, envelope::*}; use super::ClassC_Source; @@ -44,7 +45,7 @@ impl TawsFunctionality for Pda { &mut self, state: &NormalizedAircraftState, ) -> Result>, &'static dyn TawsError> { - let altitude_gnd_foot = state.altitude_ground().get::(); + let altitude_gnd_foot = state.altitude_ground().get::(); let distance_to_nearest_airport_nm = 3.0; //ToDo self.armed = distance_to_nearest_airport_nm <= 5.0; @@ -72,7 +73,7 @@ lazy_static! { Vector2::new(11_000.0, 330_000.0) ); - // Envelopes enlarged by d=0.1, to prevent floating pointing problems. + // Envelopes enlarged by d=0.1, to prevent floating pointing problems. static ref CAUTION_ENVELOPE: Envelope::<6> = Envelope::new( *LIMITS, &[ diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 6220b21..8790920 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -8,7 +8,6 @@ //! and C ABI as addiotional targets, but this did not lead anywehre usable _so far_. We are very //! open to suggestions, so please open an issue if you have some feedback. -//#![feature(return_position_impl_trait_in_trait)] #![no_std] #![deny(unsafe_code)] #![allow(dead_code)] @@ -23,10 +22,10 @@ pub mod class_c; pub mod envelope; pub mod prelude; -use prelude::*; - use core::fmt::Display; +use crate::prelude::*; + /// Abstraction for a TAWS system pub trait Taws { /// Alert source type diff --git a/opentaws/src/prelude.rs b/opentaws/src/prelude.rs index f6006e9..cd3b5ed 100644 --- a/opentaws/src/prelude.rs +++ b/opentaws/src/prelude.rs @@ -1,16 +1,15 @@ pub use self::uom::*; pub use crate::aircraft_state::{AircraftState, FlightSegment, NormalizedAircraftState}; -pub use crate::alerts::AlertLevel; pub use crate::{ - Taws, TawsAlert, TawsAlertSource, TawsAlerts, TawsError, TawsFunctionalities, TawsFunctionality, + alerts::AlertLevel, Taws, TawsAlert, TawsAlertSource, TawsAlerts, TawsError, + TawsFunctionalities, TawsFunctionality, }; -mod uom { - pub use uom::si::f64::{Angle, Length, Time, Velocity}; - pub use uom::si::{ - angle::{degree, minute as angular_minute, revolution, second as angular_second}, - length::{foot, kilometer, meter, nautical_mile}, - time::second as time_second, - velocity::{foot_per_minute, kilometer_per_hour, knot, meter_per_second}, - }; +pub mod uom { + pub use uom::fmt; + pub use uom::num_traits; + pub use uom::si; + pub use uom::si::f64; + pub use uom::si::f64::{Acceleration, Angle, Length, Ratio, Time, Velocity}; + pub use uom::si::{acceleration, angle, length, ratio, time, velocity}; } diff --git a/taws_minimal/Cargo.toml b/taws_minimal/Cargo.toml index 25e86dc..9623718 100644 --- a/taws_minimal/Cargo.toml +++ b/taws_minimal/Cargo.toml @@ -23,44 +23,22 @@ maintenance = { status = "actively-developed" } [dependencies] opentaws = { path = "../opentaws" } -aviation_database = { path = "../aviation_database" } - - -uom = { version = "0", default-features = false, features = ["f64", "si", "libm"] } -casey = "0.3" -serde = { version = "1.0", default-features = false, features = ["derive"] } - -# testing and examples -arbitrary = { version = "1", features = ["derive"], optional = true } -#async-tungstenite = { version = "*", features = [ -# "async-std-runtime", -#], optional = true } -#async-trait = { version = "0.1", optional = true } -cucumber = { version = "0", optional = true } -futures = { version = "0", optional = true } -lazy_static = { version = "1.4", optional = true } -rand = { version = "*", optional = true } -rand_pcg = { version = "*", optional = true } -#rayon = { version = "1.5", optional = true } -#serde_json = { version = "1.0", optional = true } -#smol = { version = "1", optional = true } -regex = "1" +[dev-dependencies] +arbitrary = { version = "1", default-features = false, features = ["derive"] } +cucumber = "0.19.1" +futures = "0.3.28" +lazy_static = "1.4" +rand = "0.8.5" +rand_pcg = "0.3.1" +regex = "1.8.1" +uom = { git = "https://github.com/moritz-meier/uom.git", branch = "fix-missing-libm", default-features = false, features = [ + "f64", + "si", +] } [[test]] name = "cucumber" -harness = false # Allows Cucumber to print output instead of libtest +harness = false # Allows Cucumber to print output instead of libtest path = "tests/cucumber.rs" -required-features = [ - "arbitrary", - #"async-trait", - "cucumber", - "futures", - "lazy_static", - "rand", - "rand_pcg", - #"rayon", - #"serde_json", - #"smol", -] diff --git a/taws_minimal/src/lib.rs b/taws_minimal/src/lib.rs index 846314c..c5a72df 100644 --- a/taws_minimal/src/lib.rs +++ b/taws_minimal/src/lib.rs @@ -1,3 +1,9 @@ +#![no_std] + +#[cfg(test)] +#[macro_use] +extern crate std; + use opentaws::class_c::*; use opentaws::prelude::*; diff --git a/taws_minimal/tests/cucumber.rs b/taws_minimal/tests/cucumber.rs index 281762b..5f46794 100644 --- a/taws_minimal/tests/cucumber.rs +++ b/taws_minimal/tests/cucumber.rs @@ -4,10 +4,8 @@ mod util; use cucumber::{given, then, when, World}; use opentaws::prelude::*; -use taws_minimal::{Alert, AlertSource}; -use uom::si::f64::{Length, Velocity}; -use uom::si::{length, velocity}; -use util::aircraft_state::AircraftStateGenerator; +use taws_minimal::AlertSource; + use util::constraints::Constraint; use util::parameters::*; use util::world::MyWorld; diff --git a/taws_minimal/tests/util/aircraft_state.rs b/taws_minimal/tests/util/aircraft_state.rs index ff8e489..5d7e452 100644 --- a/taws_minimal/tests/util/aircraft_state.rs +++ b/taws_minimal/tests/util/aircraft_state.rs @@ -1,9 +1,10 @@ use std::marker::PhantomData; use arbitrary::{Arbitrary, Unstructured}; -use opentaws::prelude::*; use rand::RngCore; +use opentaws::prelude::*; + use super::constraints::{AircraftStateConstraints, BouncingClamp}; #[derive(Debug, Clone)] @@ -13,20 +14,25 @@ impl<'a> Arbitrary<'a> for AircraftStateWrapper { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { let mut state = AircraftState::default(); - *state.timestamp_mut() = Time::new::(::arbitrary(u)? as f64); + *state.timestamp_mut() = + Time::new::(::arbitrary(u)? as f64); *state.position_latitude_mut() = - Angle::new::(::arbitrary(u)? as f64); + Angle::new::(::arbitrary(u)? as f64); *state.position_longitude_mut() = - Angle::new::(::arbitrary(u)? as f64); - *state.altitude_mut() = Length::new::(::arbitrary(u)? as f64); + Angle::new::(::arbitrary(u)? as f64); + *state.altitude_mut() = + Length::new::(::arbitrary(u)? as f64); *state.altitude_ground_mut() = - Length::new::(::arbitrary(u)? as f64); - *state.speed_ground_mut() = Velocity::new::(::arbitrary(u)? as f64); - *state.speed_air_mut() = Velocity::new::(::arbitrary(u)? as f64); + Length::new::(::arbitrary(u)? as f64); + *state.speed_ground_mut() = + Velocity::new::(::arbitrary(u)? as f64); + *state.speed_air_mut() = + Velocity::new::(::arbitrary(u)? as f64); *state.climb_rate_mut() = - Velocity::new::(::arbitrary(u)? as f64); - *state.heading_mut() = Angle::new::(::arbitrary(u)? as f64); - *state.track_mut() = Angle::new::(::arbitrary(u)? as f64); + Velocity::new::(::arbitrary(u)? as f64); + *state.heading_mut() = + Angle::new::(::arbitrary(u)? as f64); + *state.track_mut() = Angle::new::(::arbitrary(u)? as f64); *state.situation_mut() = Some(FlightSegment::Cruise); Ok(AircraftStateWrapper(state)) @@ -41,11 +47,10 @@ impl<'a> Arbitrary<'a> for AircraftStateWrapper { type Prng = rand_pcg::Mcg128Xsl64; pub struct AircraftStateGenerator(pub Prng); - impl Default for AircraftStateGenerator { - fn default() -> Self { - Self(Prng::new(0xcafef00dd15ea5e5)) - } + fn default() -> Self { + Self(Prng::new(0xcafef00dd15ea5e5)) + } } impl Iterator for AircraftStateGenerator { @@ -59,7 +64,7 @@ impl Iterator for AircraftStateGenerator { } let mut u = Unstructured::new(&buf); - let mut state = AircraftStateWrapper::arbitrary(&mut u).unwrap().0; // the unwrap is safe, we guarantee that enough bytes are available + let mut state = AircraftStateWrapper::arbitrary(&mut u).unwrap().0; // the unwrap is safe, we guarantee that enough bytes are available Some(state) } } diff --git a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs index f44a7f2..ea93097 100644 --- a/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs +++ b/taws_minimal/tests/util/constraints/aircraft_state_constraints.rs @@ -1,5 +1,4 @@ use opentaws::prelude::*; -use uom::si::f64::{Angle, Length, Velocity}; use super::{constraint_enforcement, Constraint, ConstraintEnforcer}; @@ -90,21 +89,33 @@ impl AircraftStateConstraints { self.situation = Some(situation); } - pub fn add_steep_approach_constraint(&mut self, is_steep: bool) { - if let Some(FlightSegment::Landing { ref mut steep_approach, .. }) = self.situation { - *steep_approach = is_steep; - } - } + pub fn add_steep_approach_constraint(&mut self, is_steep: bool) { + if let Some(FlightSegment::Landing { + ref mut steep_approach, + .. + }) = self.situation + { + *steep_approach = is_steep; + } + } - pub fn add_precision_approach_constraint(&mut self, is_precision: bool) { - if let Some(FlightSegment::Landing { ref mut precision_approach, .. }) = self.situation { - *precision_approach = is_precision; - } - } + pub fn add_precision_approach_constraint(&mut self, is_precision: bool) { + if let Some(FlightSegment::Landing { + ref mut precision_approach, + .. + }) = self.situation + { + *precision_approach = is_precision; + } + } - pub fn add_circling_approach_constraint(&mut self, is_circling: bool) { - if let Some(FlightSegment::Landing { ref mut circling_approach, .. }) = self.situation { - *circling_approach = is_circling; - } - } + pub fn add_circling_approach_constraint(&mut self, is_circling: bool) { + if let Some(FlightSegment::Landing { + ref mut circling_approach, + .. + }) = self.situation + { + *circling_approach = is_circling; + } + } } diff --git a/taws_minimal/tests/util/world.rs b/taws_minimal/tests/util/world.rs index 092c5f0..1a6a846 100644 --- a/taws_minimal/tests/util/world.rs +++ b/taws_minimal/tests/util/world.rs @@ -11,7 +11,7 @@ pub struct MyWorld { pub test_length: usize, pub phase: usize, - pub taws_constraints: AircraftStateConstraints, + pub taws_constraints: AircraftStateConstraints, pub state_gen: AircraftStateGenerator, } @@ -19,24 +19,24 @@ impl Default for MyWorld { fn default() -> Self { let mut taws_constraints = AircraftStateConstraints::default(); - let max_altitude_gnd = Length::new::(330_000.0); + let max_altitude_gnd = Length::new::(330_000.0); taws_constraints.add_altitude_ground_constraint(super::constraints::Constraint::InRange( - Length::new::(0.0), + Length::new::(0.0), max_altitude_gnd, )); - let min_max_climb_rate = Velocity::new::(680_000.0); + let min_max_climb_rate = Velocity::new::(680_000.0); taws_constraints.add_climb_rate_constraint(super::constraints::Constraint::InRange( -min_max_climb_rate, min_max_climb_rate, )); - Self { + Self { taws: MinimalTaws::new(), phases: vec![taws_constraints.clone()], test_length: 100, phase: 0, - taws_constraints: taws_constraints.clone(), + taws_constraints: taws_constraints.clone(), state_gen: AircraftStateGenerator::default(), } } From 16bab21f9cec8f2c2ca7314f074a2a1ffbda06f9 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 2 Jun 2023 13:02:14 +0200 Subject: [PATCH 52/73] fix --- taws_minimal/tests/util/parameters.rs | 32 +++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/taws_minimal/tests/util/parameters.rs b/taws_minimal/tests/util/parameters.rs index 0a969fa..3bf3835 100644 --- a/taws_minimal/tests/util/parameters.rs +++ b/taws_minimal/tests/util/parameters.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use cucumber::{Parameter}; +use cucumber::Parameter; use lazy_static::lazy_static; use regex::Regex; @@ -125,10 +125,10 @@ impl FromStr for ConstraintParameter { .map_err(|_| "invalid quantity format")?; match typ { - "equal" => match q2 { - Some(_) => Err(format!("unexpected: {}", s)), - None => Ok(Self(Constraint::Equal(q1))) - }, + "equal" => match q2 { + Some(_) => Err(format!("unexpected: {}", s)), + None => Ok(Self(Constraint::Equal(q1))), + }, "at least" => match q2 { Some(_) => Err(format!("unexpected: {}", s)), None => Ok(Self(Constraint::AtLeast(q1))), @@ -172,7 +172,7 @@ pub struct FlightSegmentParameter(FlightSegment); impl From for FlightSegment { fn from(segment: FlightSegmentParameter) -> Self { - segment.0 + segment.0 } } @@ -180,20 +180,24 @@ impl FromStr for FlightSegmentParameter { type Err = String; fn from_str(s: &str) -> Result { - let mut segment = s.trim().to_lowercase(); + let mut segment = s.trim().to_lowercase(); segment.retain(|c| !c.is_whitespace()); match segment.as_str() { - "cruise" => Ok(Self(FlightSegment::Cruise)), - "take-off" => Ok(Self(FlightSegment::TakeOff)), - "approach" | "landing" => Ok(Self(FlightSegment::Landing { circling_approach: false, precision_approach: false, steep_approach: false })), - "go-around" => Ok(Self(FlightSegment::GoAround)), - _ => Err(format!("invalid flight segment: {}", s)), - } + "cruise" => Ok(Self(FlightSegment::Cruise)), + "take-off" => Ok(Self(FlightSegment::TakeOff)), + "approach" | "landing" => Ok(Self(FlightSegment::Landing { + circling_approach: false, + precision_approach: false, + steep_approach: false, + })), + "go-around" => Ok(Self(FlightSegment::GoAround)), + _ => Err(format!("invalid flight segment: {}", s)), + } } } impl Parameter for FlightSegmentParameter { - const NAME: &'static str = "flight-segment"; + const NAME: &'static str = "flight-segment"; const REGEX: &'static str = r"(?:cruise|take-off|landing|go-around|approach)"; } From ff4e7ed0f42cfdf59a823edb27bd4e5f11640dca Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 2 Jun 2023 13:25:44 +0200 Subject: [PATCH 53/73] fix --- .github/workflows/rust.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2d9fb43..8c22299 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: main on: push: - branches: [ main, staging ] + branches: [main, staging] pull_request: - branches: [ main, staging ] + branches: [main, staging] jobs: format: @@ -13,9 +13,9 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: - toolchain: stable - components: rustfmt - override: true + toolchain: stable + components: rustfmt + override: true - name: Run tests run: cargo fmt -- --check @@ -56,9 +56,9 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - uses: actions-rs/toolchain@v1 with: - toolchain: nightly - components: clippy - override: true + toolchain: nightly + components: clippy + override: true - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -84,12 +84,12 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - uses: actions-rs/toolchain@v1 with: - toolchain: nightly - components: clippy - override: true + toolchain: nightly + components: clippy + override: true - name: Generate code coverage run: | - cargo +nightly tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml + cargo +nightly tarpaulin --verbose --all-features --workspace --implicit-test-threads --timeout 120 --out Xml - name: Upload to codecov.io uses: codecov/codecov-action@v1 with: From c5a119f4dfe8861e072ac0c945b25486c65b404e Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 11:04:18 +0200 Subject: [PATCH 54/73] Add armv7a-none-eabi target --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index f7b0001..79a7e3b 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,7 @@ stable.cargo stable.rustc stable.rustfmt + targets.armv7a-none-eabi.stable.rust-std ]; naersk-lib = (naersk.lib."${system}".override { cargo = rust-toolchain; From fc5e4c53fe7568c81e84e6a73855aa68e0262984 Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 11:24:08 +0200 Subject: [PATCH 55/73] Readd serde support Add rust-analyzer in correct version --- Cargo.lock | 2 ++ flake.nix | 2 +- opentaws/Cargo.toml | 3 +++ opentaws/src/aircraft_state.rs | 3 ++- opentaws/src/alerts.rs | 2 ++ 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d28399a..9a89504 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -828,6 +828,7 @@ dependencies = [ "heapless", "lazy_static", "nalgebra", + "serde", "uom", ] @@ -1304,6 +1305,7 @@ version = "0.34.0" source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4ddb11b11b11b333a98185c19336d16c85e22c9c" dependencies = [ "num-traits", + "serde", "typenum", ] diff --git a/flake.nix b/flake.nix index 79a7e3b..e866ee4 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ let pkgs = import nixpkgs { inherit system; }; rust-toolchain = with fenix.packages.${system}; combine [ - rust-analyzer + stable.rust-analyzer stable.cargo stable.rustc stable.rustfmt diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index daa51c5..c9d2fcd 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -22,8 +22,11 @@ is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS maintenance = { status = "actively-developed" } [features] +default = ["use-serde"] +use-serde = ["serde", "uom/use_serde"] [dependencies] +serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] } lazy_static = { version = "1", default-features = false, features = [ "spin_no_std", ] } diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 02267ac..55e8cd2 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -30,6 +30,7 @@ pub struct Normalized; pub type NormalizedAircraftState = AircraftState; /// Represents the current state of an aircraft +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default)] pub struct AircraftState { /// Time when this aircraft state was emitted @@ -240,7 +241,6 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { - use ::uom::num_traits::Float; let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) .get::() .floor() as i64) @@ -337,6 +337,7 @@ AircrafState: {{ } /// Represents a flight segment +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FlightSegment { /// The aircraft is in cruise flight situation diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 19e86d2..92255af 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -4,6 +4,7 @@ use heapless::FnvIndexMap; use crate::prelude::*; /// TAWS Alert levels +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlertLevel { /// The level or category of alert for conditions that require immediate flight crew awareness @@ -20,6 +21,7 @@ pub enum AlertLevel { } /// Represents a TAWS alert +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Alert { /// The source resp. the TAWS functionallity which emitted this alert From f711303dd3abe281963523846e7845021a93fc49 Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 13:53:29 +0200 Subject: [PATCH 56/73] Readd import because it is needed when using the opentaws crate --- opentaws/src/aircraft_state.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 55e8cd2..20826fa 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -241,6 +241,9 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { + #[allow(unused_imports)] + use crate::prelude::uom::num_traits::Float; + let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) .get::() .floor() as i64) From 569f06d8dd9e2c55f337607755d4f8a381064613 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 20 Sep 2023 15:35:12 +0200 Subject: [PATCH 57/73] feat: update heapless update heapless dependency to current main branch. last release on crates.io is over a year old. --- Cargo.lock | 468 +++++++++++++++++----------------------- opentaws/Cargo.toml | 3 +- opentaws/src/alerts.rs | 14 +- opentaws/src/class_c.rs | 12 +- 4 files changed, 202 insertions(+), 295 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a89504..f47c360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,61 +2,40 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" -dependencies = [ - "memchr", -] - [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -72,9 +51,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -82,9 +61,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "approx" @@ -106,20 +85,20 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.37", ] [[package]] name = "atomic-polyfill" -version = "0.1.11" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" dependencies = [ "critical-section", ] @@ -130,7 +109,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] @@ -147,11 +126,17 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "bstr" -version = "1.4.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", "serde", @@ -171,9 +156,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -183,24 +171,22 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.7" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", "terminal_size", @@ -208,21 +194,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.37", ] [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -232,32 +218,22 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "critical-section" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" - -[[package]] -name = "ctor" -version = "0.2.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4056f63fce3b82d852c3da92b08ea59959890813a7f4ce9c0ff85b10cf301b" -dependencies = [ - "quote", - "syn 2.0.16", -] +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] name = "cucumber" @@ -320,13 +296,13 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.37", ] [[package]] @@ -348,9 +324,9 @@ checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" @@ -360,9 +336,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -441,7 +417,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.37", ] [[package]] @@ -476,9 +452,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -502,24 +478,13 @@ dependencies = [ "typed-builder", ] -[[package]] -name = "ghost" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - [[package]] name = "globset" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" dependencies = [ - "aho-corasick 0.7.20", + "aho-corasick", "bstr", "fnv", "log", @@ -532,34 +497,24 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "ignore", "walkdir", ] [[package]] name = "hash32" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - [[package]] name = "heapless" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +version = "0.8.0" +source = "git+https://github.com/japaric/heapless.git#644653bf3b831c6bb4963be2de24804acf5e5001" dependencies = [ "atomic-polyfill", "hash32", @@ -592,12 +547,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - [[package]] name = "humantime" version = "2.1.0" @@ -629,36 +578,9 @@ checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" [[package]] name = "inventory" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7741301a6d6a9b28ce77c0fb77a4eb116b6bc8f3bef09923f7743d059c4157d3" -dependencies = [ - "ctor", - "ghost", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "is-terminal" -version = "0.4.7" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] +checksum = "e1be380c410bf0595e94992a648ea89db4dd3f3354ba54af206fd2a68cf5ac8e" [[package]] name = "itertools" @@ -671,9 +593,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "lazy_static" @@ -686,15 +608,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libm" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linked-hash-map" @@ -704,15 +626,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.7" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -720,18 +642,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "minimal-lexical" @@ -741,9 +660,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nalgebra" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" +checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" dependencies = [ "approx", "num-complex", @@ -765,9 +684,9 @@ dependencies = [ [[package]] name = "nom_locate" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e299bf5ea7b212e811e71174c5d1a5d065c4c0ad0c8691ecb1f97e3e66025e" +checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" dependencies = [ "bytecount", "memchr", @@ -776,9 +695,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" dependencies = [ "num-traits", ] @@ -806,9 +725,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -816,15 +735,14 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opentaws" version = "0.1.0" dependencies = [ - "hash32", "heapless", "lazy_static", "nalgebra", @@ -834,9 +752,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "peg" @@ -867,9 +785,9 @@ checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -885,18 +803,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.57" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -942,13 +860,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ - "aho-corasick 1.0.1", + "aho-corasick", "memchr", - "regex-syntax 0.7.1", + "regex-syntax 0.7.5", ] [[package]] @@ -959,9 +889,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rustc_version" @@ -974,13 +904,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys 0.48.0", @@ -988,9 +917,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -1003,9 +932,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sealed" @@ -1033,35 +962,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.37", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1082,9 +1011,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -1102,9 +1031,9 @@ dependencies = [ [[package]] name = "smawk" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "spin" @@ -1146,9 +1075,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -1205,9 +1134,9 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ "rustix", "windows-sys 0.48.0", @@ -1226,22 +1155,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.37", ] [[package]] @@ -1267,25 +1196,21 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-linebreak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" -dependencies = [ - "hashbrown", - "regex", -] +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" @@ -1295,14 +1220,14 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "uom" -version = "0.34.0" -source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4ddb11b11b11b333a98185c19336d16c85e22c9c" +version = "0.35.0" +source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4afd75d1a46b7256db04e9551897a1e0219df2ef" dependencies = [ "num-traits", "serde", @@ -1315,17 +1240,11 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -1370,17 +1289,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.42.2", ] [[package]] @@ -1389,22 +1302,37 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1415,9 +1343,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -1427,9 +1355,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -1439,9 +1367,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -1451,9 +1379,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -1463,9 +1391,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -1475,9 +1403,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -1487,6 +1415,6 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index c9d2fcd..042328a 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -30,8 +30,7 @@ serde = { version = "1.0", default-features = false, optional = true, features = lazy_static = { version = "1", default-features = false, features = [ "spin_no_std", ] } -heapless = "0.7.16" -hash32 = "0.2.1" +heapless = { git = "https://github.com/japaric/heapless.git" } nalgebra = { version = "0.32.2", default-features = false, features = ["libm"] } uom = { git = "https://github.com/moritz-meier/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 92255af..398d618 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,4 +1,4 @@ -use hash32::Hash; +use core::hash::Hash; use heapless::FnvIndexMap; use crate::prelude::*; @@ -132,9 +132,8 @@ mod tests { use core::slice::Iter; use super::*; - use hash32::{Hash, Hasher}; - #[derive(Copy, Clone, Debug, PartialEq, Eq)] + #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] enum TestClass { A, B, @@ -156,15 +155,6 @@ mod tests { } } - impl Hash for TestClass { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - state.write(&(*self as usize).to_le_bytes()); - } - } - type TestAlert = Alert; type TestAlerts = Alerts; diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index 65da407..f5a7c11 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -5,14 +5,13 @@ mod mode3; mod pda; use core::{fmt::Display, slice::Iter}; -use hash32::{Hash, Hasher}; use crate::alerts::Alert; use crate::prelude::*; pub use {ffac::*, /*flta::*,*/ mode1::*, mode3::*, pda::*}; -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[allow(non_camel_case_types)] pub enum ClassC_Source { Ffac, @@ -55,15 +54,6 @@ impl IntoIterator for ClassC_Source { } } -impl Hash for ClassC_Source { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - state.write(&(*self as usize).to_le_bytes()) - } -} - pub struct ClassC { ffac: Ffac, //flta: flta::Flta, From 1b22715e4315f2432500096e16c39ce7f0e8f625 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 20 Sep 2023 19:31:03 +0200 Subject: [PATCH 58/73] feat: impl IntoIterator for TawsAlerts --- Cargo.lock | 12 ++++---- opentaws/src/alerts.rs | 62 ++++++++++++++++++++++++++++++++++++------ opentaws/src/lib.rs | 10 +++++-- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f47c360..957f0a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -904,9 +904,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.13" +version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ "bitflags 2.4.0", "errno", @@ -1274,9 +1274,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 398d618..4382c1a 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -89,13 +89,49 @@ where } } -impl Alerts +impl<'a, Alert: TawsAlert> IntoIterator for &'a Alerts where Alert::AlertSource: Hash, { - /// Returns an iterator over all active alerts. - pub fn alerts(&self) -> impl Iterator + '_ { - self.alerts.values() + type Item = &'a Alert; + type IntoIter = AlertsIter<'a, Alert>; + + fn into_iter(self) -> Self::IntoIter { + AlertsIter::new(self.alerts.iter()) + } +} + +type AlertsIterInner<'a, Alert> = core::iter::Map< + heapless::IndexMapIter<'a, ::AlertSource, Alert>, + fn((&'a ::AlertSource, &'a Alert)) -> &'a Alert, +>; + +pub struct AlertsIter<'a, Alert: TawsAlert> +where + Alert::AlertSource: Hash, +{ + iter: AlertsIterInner<'a, Alert>, +} + +impl<'a, Alert: TawsAlert> AlertsIter<'a, Alert> +where + Alert::AlertSource: Hash, +{ + fn new(iter: heapless::IndexMapIter<'a, Alert::AlertSource, Alert>) -> Self { + Self { + iter: iter.map(|(_, alert)| alert), + } + } +} + +impl<'a, Alert: TawsAlert> Iterator for AlertsIter<'a, Alert> +where + Alert::AlertSource: Hash, +{ + type Item = &'a Alert; + + fn next(&mut self) -> Option { + self.iter.next() } } @@ -118,8 +154,6 @@ where } fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool { - self.alerts.contains_key(&alert_src); - match self.alerts.get(&alert_src) { Some(alert) => alert.level() <= min_level, None => false, @@ -215,7 +249,7 @@ mod tests { } #[test] - fn alerts_get() { + fn alerts_into_iter() { let mut alerts = TestAlerts::default(); let alert1: TestAlert = (TestClass::A, AlertLevel::Annunciation).into(); let alert2: TestAlert = (TestClass::B, AlertLevel::Caution).into(); @@ -225,6 +259,18 @@ mod tests { alerts.insert(alert2); alerts.insert(alert3); - assert!(alerts.alerts().count() == 3) + assert!(alerts.into_iter().count() == 3); + + alerts + .into_iter() + .any(|alert| *alert == (TestClass::A, AlertLevel::Annunciation).into()); + + alerts + .into_iter() + .any(|alert| *alert == (TestClass::B, AlertLevel::Caution).into()); + + alerts + .into_iter() + .any(|alert| *alert == (TestClass::C, AlertLevel::Warning).into()); } } diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 8790920..58112ec 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -27,7 +27,10 @@ use core::fmt::Display; use crate::prelude::*; /// Abstraction for a TAWS system -pub trait Taws { +pub trait Taws +where + for<'a> &'a Self::Alerts: IntoIterator, +{ /// Alert source type type AlertSource: TawsAlertSource; @@ -187,7 +190,10 @@ pub trait TawsFunctionality { } /// Abstraction for a set of TAWS alerts -pub trait TawsAlerts { +pub trait TawsAlerts +where + for<'a> &'a Self: IntoIterator, +{ type AlertSource: TawsAlertSource; /// Alert type From 0744334f1f312bccedde285701d9177cc776f50e Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 20 Sep 2023 21:15:07 +0200 Subject: [PATCH 59/73] fix: ClassC_Source::into_iter --- opentaws/src/class_c.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index f5a7c11..ebba2b7 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -46,11 +46,10 @@ impl TawsAlertSource for ClassC_Source { impl IntoIterator for ClassC_Source { type Item = &'static ClassC_Source; - type IntoIter = Iter<'static, ClassC_Source>; fn into_iter(self) -> Self::IntoIter { - [Self::Ffac, Self::Mode1, Self::Mode3, Self::Pda].iter() + ClassC_Source::ALERT_SOURCES.iter() } } From 867980a0735b4854dcf43115ab732a0554d26058 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Wed, 20 Sep 2023 21:41:41 +0200 Subject: [PATCH 60/73] fix: TawsAlertSources::NUM_ALERT_SOURCES replaced by const MAX_NUM_ALERT_SOURCES maybe one day we will get const generic expr in stable rust --- opentaws/src/alerts.rs | 9 ++------- opentaws/src/class_c.rs | 1 - opentaws/src/lib.rs | 4 ++-- opentaws/src/prelude.rs | 2 +- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 4382c1a..754cf1d 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -71,11 +71,7 @@ pub struct Alerts where Alert::AlertSource: Hash, { - alerts: FnvIndexMap< - Alert::AlertSource, - Alert, - 64, /*ToDo: use ::NUM_ALERT_SOURCES or count the available alert sources with a macro*/ - >, + alerts: FnvIndexMap, } impl Default for Alerts @@ -175,8 +171,7 @@ mod tests { } impl TawsAlertSource for TestClass { - const NUM_ALERT_SOURCES: usize = 3; - const ALERT_SOURCES: &'static [Self] = &[]; + const ALERT_SOURCES: &'static [Self] = &[TestClass::A, TestClass::B, TestClass::C]; } impl IntoIterator for TestClass { diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index ebba2b7..aa10e02 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -34,7 +34,6 @@ impl Display for ClassC_Source { } impl TawsAlertSource for ClassC_Source { - const NUM_ALERT_SOURCES: usize = 5; const ALERT_SOURCES: &'static [Self] = &[ ClassC_Source::Ffac, //ClassC_Source::Flta, diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 58112ec..171ad7b 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -224,10 +224,10 @@ pub trait TawsAlert { fn level(&self) -> AlertLevel; } +pub const MAX_NUM_ALERT_SOURCES: usize = 64; + /// Abstraction for an alert source pub trait TawsAlertSource: Clone + Copy + Eq + 'static { - const NUM_ALERT_SOURCES: usize; - const ALERT_SOURCES: &'static [Self]; } diff --git a/opentaws/src/prelude.rs b/opentaws/src/prelude.rs index cd3b5ed..7c64298 100644 --- a/opentaws/src/prelude.rs +++ b/opentaws/src/prelude.rs @@ -2,7 +2,7 @@ pub use self::uom::*; pub use crate::aircraft_state::{AircraftState, FlightSegment, NormalizedAircraftState}; pub use crate::{ alerts::AlertLevel, Taws, TawsAlert, TawsAlertSource, TawsAlerts, TawsError, - TawsFunctionalities, TawsFunctionality, + TawsFunctionalities, TawsFunctionality, MAX_NUM_ALERT_SOURCES, }; pub mod uom { From bea17e922f5c03c9f1440dbf4bc6137cfa8a2f1a Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 21 Sep 2023 02:07:43 +0200 Subject: [PATCH 61/73] feat: alert prioritization --- opentaws/src/alerts.rs | 102 ++++++++++++++++++++++++++++++++++++++-- opentaws/src/class_c.rs | 16 ++++++- opentaws/src/lib.rs | 36 ++++++++++++-- 3 files changed, 143 insertions(+), 11 deletions(-) diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 754cf1d..8b3ea64 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,7 +1,9 @@ use core::hash::Hash; use heapless::FnvIndexMap; -use crate::prelude::*; +use crate::{ + prelude::*, TawsAlertSourcePrioritization, TawsAlertsPrioritizationExt, TawsPrioritizedAlerts, +}; /// TAWS Alert levels #[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] @@ -138,6 +140,10 @@ where type Alert = Alert; type AlertSource = Alert::AlertSource; + fn get(&self, alert_src: Self::AlertSource) -> Option<&Self::Alert> { + self.alerts.get(&alert_src) + } + fn insert(&mut self, new_alert: Alert) { let current_alert = self.alerts.get(&new_alert.source()); @@ -148,12 +154,42 @@ where .unwrap(); //ToDo } } +} + +impl TawsAlertsPrioritizationExt for T +where + T::AlertSource: TawsAlertSourcePrioritization, + for<'a> &'a Self: IntoIterator, +{ + type PrioritizedAlerts<'a> = PrioritizedAlerts<'a, Self::Alert> where Self: 'a; + + fn prioritize(&self) -> Self::PrioritizedAlerts<'_> { + let mut prioritized: [Option<&T::Alert>; MAX_NUM_ALERT_SOURCES] = + [None; MAX_NUM_ALERT_SOURCES]; + + ::PRIORITIZATION + .iter() + .filter_map(|(src, level)| self.get_min(*src, *level)) + .enumerate() + .for_each(|(i, alert)| prioritized[i] = Some(alert)); + + Self::PrioritizedAlerts { prioritized } + } +} + +pub struct PrioritizedAlerts<'a, Alert: TawsAlert> { + prioritized: [Option<&'a Alert>; MAX_NUM_ALERT_SOURCES], +} + +impl<'a, Alert: TawsAlert> TawsPrioritizedAlerts<'a> for PrioritizedAlerts<'a, Alert> { + type Alert = Alert; - fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool { - match self.alerts.get(&alert_src) { - Some(alert) => alert.level() <= min_level, - None => false, + fn index(&self, idx: usize) -> Option<&'a Self::Alert> { + if !(0..MAX_NUM_ALERT_SOURCES).contains(&idx) { + return None; } + + self.prioritized[idx] } } @@ -174,6 +210,14 @@ mod tests { const ALERT_SOURCES: &'static [Self] = &[TestClass::A, TestClass::B, TestClass::C]; } + impl TawsAlertSourcePrioritization for TestClass { + const PRIORITIZATION: &'static [(Self, AlertLevel)] = &[ + (TestClass::A, AlertLevel::Caution), + (TestClass::B, AlertLevel::Warning), + (TestClass::C, AlertLevel::Annunciation), + ]; + } + impl IntoIterator for TestClass { type Item = &'static TestClass; @@ -268,4 +312,52 @@ mod tests { .into_iter() .any(|alert| *alert == (TestClass::C, AlertLevel::Warning).into()); } + + #[test] + fn alert_prioritization() { + let mut alerts = TestAlerts::default(); + let alert1: TestAlert = (TestClass::B, AlertLevel::Warning).into(); + + alerts.insert(alert1); + + { + let prioritzed = alerts.prioritize(); + assert!(*prioritzed.index(0).unwrap() == (TestClass::B, AlertLevel::Warning).into()); + assert!(prioritzed.index(1).is_none()); + } + + let alert2: TestAlert = (TestClass::C, AlertLevel::Caution).into(); + alerts.insert(alert2); + + { + let prioritzed = alerts.prioritize(); + assert!(*prioritzed.index(0).unwrap() == (TestClass::B, AlertLevel::Warning).into()); + assert!(*prioritzed.index(1).unwrap() == (TestClass::C, AlertLevel::Caution).into()); + assert!(prioritzed.index(2).is_none()); + } + + let alert3: TestAlert = (TestClass::A, AlertLevel::Caution).into(); + alerts.insert(alert3); + + { + let prioritzed = alerts.prioritize(); + + assert!(*prioritzed.index(0).unwrap() == (TestClass::A, AlertLevel::Caution).into()); + assert!(*prioritzed.index(1).unwrap() == (TestClass::B, AlertLevel::Warning).into()); + assert!(*prioritzed.index(2).unwrap() == (TestClass::C, AlertLevel::Caution).into()); + assert!(prioritzed.index(3).is_none()); + } + + let alert4: TestAlert = (TestClass::A, AlertLevel::Annunciation).into(); + alerts.insert(alert4); + + { + let prioritzed = alerts.prioritize(); + + assert!(*prioritzed.index(0).unwrap() == (TestClass::A, AlertLevel::Caution).into()); + assert!(*prioritzed.index(1).unwrap() == (TestClass::B, AlertLevel::Warning).into()); + assert!(*prioritzed.index(2).unwrap() == (TestClass::C, AlertLevel::Caution).into()); + assert!(prioritzed.index(3).is_none()); + } + } } diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index aa10e02..f283af9 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -6,7 +6,7 @@ mod pda; use core::{fmt::Display, slice::Iter}; -use crate::alerts::Alert; +use crate::{alerts::Alert, TawsAlertSourcePrioritization}; use crate::prelude::*; pub use {ffac::*, /*flta::*,*/ mode1::*, mode3::*, pda::*}; @@ -43,6 +43,18 @@ impl TawsAlertSource for ClassC_Source { ]; } +impl TawsAlertSourcePrioritization for ClassC_Source { + const PRIORITIZATION: &'static [(Self, AlertLevel)] = &[ + (ClassC_Source::Mode1, AlertLevel::Warning), + //(ClassC_Source::Flta, AlertLevel::Warning), + //(ClassC_Source::Flta, AlertLevel::Caution), + (ClassC_Source::Pda, AlertLevel::Caution), + (ClassC_Source::Ffac, AlertLevel::Annunciation), + (ClassC_Source::Mode1, AlertLevel::Caution), + (ClassC_Source::Mode3, AlertLevel::Caution), + ]; +} + impl IntoIterator for ClassC_Source { type Item = &'static ClassC_Source; type IntoIter = Iter<'static, ClassC_Source>; @@ -61,6 +73,8 @@ pub struct ClassC { } impl ClassC { + // ::default() does not work here, we may need params in the future + #[allow(clippy::new_without_default)] pub fn new() -> Self { ClassC { ffac: Ffac::default(), diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 171ad7b..4ec4f34 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -199,17 +199,39 @@ where /// Alert type type Alert: TawsAlert; + fn get(&self, alert_src: Self::AlertSource) -> Option<&Self::Alert>; + + fn get_min(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> Option<&Self::Alert> { + self.get(alert_src) + .and_then(|alert| (alert.level() <= min_level).then_some(alert)) + } + + fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool { + self.get_min(alert_src, min_level).is_some() + } + /// Inserts the specified alert into the set. /// Already existing alerts are replaced if the [new_alert] has a higher alert level. /// # Arguments /// * `new_alert` - the new alert which is added to the set of alerts fn insert(&mut self, new_alert: Self::Alert); +} - /// Returns whether an alert from the given source with at least the specified alert level is active. - /// # Arguments - /// * `alert_src` - The alert source to check for. - /// * `min_level` - The inclusive min level to check for. - fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool; +pub trait TawsAlertsPrioritizationExt: TawsAlerts +where + for<'a> &'a Self: IntoIterator, +{ + type PrioritizedAlerts<'a>: TawsPrioritizedAlerts<'a, Alert = Self::Alert> + where + Self: 'a; + + fn prioritize(&self) -> Self::PrioritizedAlerts<'_>; +} + +pub trait TawsPrioritizedAlerts<'a> { + type Alert: TawsAlert; + + fn index(&self, idx: usize) -> Option<&'a Self::Alert>; } /// Abstraction for a TAWS alert @@ -231,4 +253,8 @@ pub trait TawsAlertSource: Clone + Copy + Eq + 'static { const ALERT_SOURCES: &'static [Self]; } +pub trait TawsAlertSourcePrioritization: TawsAlertSource { + const PRIORITIZATION: &'static [(Self, AlertLevel)]; +} + pub trait TawsError: core::fmt::Debug + Display {} From 3acfcb1e96e91c035029ded8b3afff173c01c5d7 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Thu, 21 Sep 2023 15:01:37 +0200 Subject: [PATCH 62/73] docs docs --- opentaws/src/alerts.rs | 3 ++ opentaws/src/class_c.rs | 2 ++ opentaws/src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 8b3ea64..f2d44ca 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -156,6 +156,8 @@ where } } +// Implements the alert prioritization for all `TawsAlerts` implementing types, +// if the associated `TawsAlerts::AlertSource` type implements `TawsAlertSourcePrioritization`. impl TawsAlertsPrioritizationExt for T where T::AlertSource: TawsAlertSourcePrioritization, @@ -177,6 +179,7 @@ where } } +/// Sorted set of prioritized alerts. pub struct PrioritizedAlerts<'a, Alert: TawsAlert> { prioritized: [Option<&'a Alert>; MAX_NUM_ALERT_SOURCES], } diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index f283af9..f40a835 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -43,6 +43,8 @@ impl TawsAlertSource for ClassC_Source { ]; } +// Class C alert prioritization. +// DO-367 Section 2.2.3.2.4 Alert Prioritization. impl TawsAlertSourcePrioritization for ClassC_Source { const PRIORITIZATION: &'static [(Self, AlertLevel)] = &[ (ClassC_Source::Mode1, AlertLevel::Warning), diff --git a/opentaws/src/lib.rs b/opentaws/src/lib.rs index 4ec4f34..12ea2fb 100644 --- a/opentaws/src/lib.rs +++ b/opentaws/src/lib.rs @@ -189,7 +189,7 @@ pub trait TawsFunctionality { ) -> Result, &'static dyn TawsError>; // Result ? } -/// Abstraction for a set of TAWS alerts +/// Abstraction for a set of `TawsAlert`s. pub trait TawsAlerts where for<'a> &'a Self: IntoIterator, @@ -199,13 +199,25 @@ where /// Alert type type Alert: TawsAlert; + /// Returns the alert with the specified `alert_src`, if one exists; otherwise `None`. + /// # Arguments + /// * `alert_src` - The `Self::AlertSource` to look for. fn get(&self, alert_src: Self::AlertSource) -> Option<&Self::Alert>; + /// Returns the alert with the specified `alert_src` if one exists and if the alert has an `AlertLevel` + /// greater than or equal to `min_level`; otherwise `None`. + /// # Arguments + /// * `alert_src` - The `Self::AlertSource` to look for. + /// * `min_level`- Minimum `AlertLevel` to look for. fn get_min(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> Option<&Self::Alert> { self.get(alert_src) .and_then(|alert| (alert.level() <= min_level).then_some(alert)) } + /// Checks whether an alert with the specified `alert_src` exists that has a minimum `AlertLevel` of `min_level`. + /// # Arguments + /// * `alert_src` - The `Self::AlertSource` to check. + /// * `min_level` - The minimum `AlertLevel`. fn is_alert_active(&self, alert_src: Self::AlertSource, min_level: AlertLevel) -> bool { self.get_min(alert_src, min_level).is_some() } @@ -217,6 +229,8 @@ where fn insert(&mut self, new_alert: Self::Alert); } +/// Extension trait for `TawsAlerts` that implements alert prioritization +/// if the associated `TawsAlertSource` implements `TawsAlertSourcePrioritization`. pub trait TawsAlertsPrioritizationExt: TawsAlerts where for<'a> &'a Self: IntoIterator, @@ -225,12 +239,22 @@ where where Self: 'a; + /// Prioritize alerts by the associated `TawsAlertSourcePrioritization` implementation. fn prioritize(&self) -> Self::PrioritizedAlerts<'_>; } +/// Abstraction for a sorted set of `TawsAlert`s. pub trait TawsPrioritizedAlerts<'a> { type Alert: TawsAlert; + /// Gets the alert at index `idx` from the prioritized (sorted) set of alerts, + /// if one exists at the given `idx`; otherwise `None`.
+ /// Low indices describe high priority. Index 0 contains the alert with the highest priority + /// or `None` if no alert matches any of the rules in `TawsAlertSourcePrioritization`.
+ /// It is important to note that an empty set here does not imply absent of alerts in general. + /// It only mean that no alert matched any of the prioritization rules. + /// # Arguments + /// * `idx` - The index at which the prioritized (sorted) set of alerts is accessed. fn index(&self, idx: usize) -> Option<&'a Self::Alert>; } @@ -246,6 +270,7 @@ pub trait TawsAlert { fn level(&self) -> AlertLevel; } +/// Maximum number of supported alert sources. pub const MAX_NUM_ALERT_SOURCES: usize = 64; /// Abstraction for an alert source @@ -253,7 +278,41 @@ pub trait TawsAlertSource: Clone + Copy + Eq + 'static { const ALERT_SOURCES: &'static [Self]; } +/// Alert prioritization trait. Describes how `TawsAlert`s should be prioritized. pub trait TawsAlertSourcePrioritization: TawsAlertSource { + /// Prioritization rules that assign priorities to `TawsAlert`s. + /// # Example + /// ``` + /// # use opentaws::prelude::*; + /// # enum AlertSource { Mode1, Mode3, Flta, Pda, Ffac } + /// &[ + /// (AlertSource::Mode1, AlertLevel::Warning), + /// (AlertSource::Flta, AlertLevel::Warning), + /// (AlertSource::Flta, AlertLevel::Caution), + /// (AlertSource::Pda, AlertLevel::Caution), + /// (AlertSource::Ffac, AlertLevel::Annunciation), + /// (AlertSource::Mode1, AlertLevel::Caution), + /// (AlertSource::Mode3, AlertLevel::Caution), + /// ]; + /// ``` + /// + /// * All Mode1 alerts with level Warning or higher will be assigned priority 0 (highest priority). + /// * All Flta alerts with level Warning or higher will be assigned priority 1. + /// * All Mode1 alerts with level Caution or higher will be assigned priority 5. + /// + /// For example these alerts:
+ /// `{(Mode3, Annunciation), (Mode1, Caution), (Flta, Warning)}`
+ /// will be sorted into this order:
+ /// `[(Flta, Warning), (Mode1, Caution)]` + /// + /// * `(Flta, Warning)` has a higher priority than the other alerts because of rule 2. + /// * `(Mode1, Caution)` has a lower priority than the Flta alert because of rule 6 but a higher priority than `(Mode3, Annunciation)`. + /// * `(Mode3, Annunciation)` has no priotity because it does not match any rule and is therefore ignored. + /// + /// Alerts that do not fit into any rule cannot be prioritized, because the prioritization would be arbitrary and thus not reliable.
+ /// If all alerts should be present in the sorted collection, + /// consider adding a catch-all rules for all alert sources at the end with the lowest possible alert level (Annunciation).
+ /// By doing this all alert sources get a priority assigned and the arbitrariness is prevented. const PRIORITIZATION: &'static [(Self, AlertLevel)]; } From a79427637bbbb76004475a77309446bf08df8c7f Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Tue, 10 Oct 2023 15:52:13 +0200 Subject: [PATCH 63/73] Update rust.yml fix: code coverage typo --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8c22299..9761287 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -89,7 +89,7 @@ jobs: override: true - name: Generate code coverage run: | - cargo +nightly tarpaulin --verbose --all-features --workspace --implicit-test-threads --timeout 120 --out Xml + cargo +nightly tarpaulin --verbose --all-features --workspace --implicit-test-threads --timeout 120 --out xml - name: Upload to codecov.io uses: codecov/codecov-action@v1 with: From a0ec3b0577d1338555df299ba6d073caf1a4bb6a Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 13:53:29 +0200 Subject: [PATCH 64/73] Revert "Readd import because it is needed when using the opentaws crate" This reverts commit f711303dd3abe281963523846e7845021a93fc49. --- opentaws/src/aircraft_state.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 20826fa..55e8cd2 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -241,9 +241,6 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { - #[allow(unused_imports)] - use crate::prelude::uom::num_traits::Float; - let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) .get::() .floor() as i64) From d0c236dfe37e0373bce1501d57b04127c4bc9f40 Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 11:24:08 +0200 Subject: [PATCH 65/73] Revert "Readd serde support" This reverts commit fc5e4c53fe7568c81e84e6a73855aa68e0262984. --- Cargo.lock | 2 -- flake.nix | 2 +- opentaws/Cargo.toml | 3 --- opentaws/src/aircraft_state.rs | 3 +-- opentaws/src/alerts.rs | 2 -- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 957f0a8..2471655 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -746,7 +746,6 @@ dependencies = [ "heapless", "lazy_static", "nalgebra", - "serde", "uom", ] @@ -1230,7 +1229,6 @@ version = "0.35.0" source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4afd75d1a46b7256db04e9551897a1e0219df2ef" dependencies = [ "num-traits", - "serde", "typenum", ] diff --git a/flake.nix b/flake.nix index e866ee4..79a7e3b 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ let pkgs = import nixpkgs { inherit system; }; rust-toolchain = with fenix.packages.${system}; combine [ - stable.rust-analyzer + rust-analyzer stable.cargo stable.rustc stable.rustfmt diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 042328a..4c02e69 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -22,11 +22,8 @@ is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS maintenance = { status = "actively-developed" } [features] -default = ["use-serde"] -use-serde = ["serde", "uom/use_serde"] [dependencies] -serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] } lazy_static = { version = "1", default-features = false, features = [ "spin_no_std", ] } diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 55e8cd2..02267ac 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -30,7 +30,6 @@ pub struct Normalized; pub type NormalizedAircraftState = AircraftState; /// Represents the current state of an aircraft -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default)] pub struct AircraftState { /// Time when this aircraft state was emitted @@ -241,6 +240,7 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { + use ::uom::num_traits::Float; let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) .get::() .floor() as i64) @@ -337,7 +337,6 @@ AircrafState: {{ } /// Represents a flight segment -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FlightSegment { /// The aircraft is in cruise flight situation diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index f2d44ca..28e60aa 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -6,7 +6,6 @@ use crate::{ }; /// TAWS Alert levels -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlertLevel { /// The level or category of alert for conditions that require immediate flight crew awareness @@ -23,7 +22,6 @@ pub enum AlertLevel { } /// Represents a TAWS alert -#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Alert { /// The source resp. the TAWS functionallity which emitted this alert From fcf8b4db406d15757e83f9cb72d7dccde6f39eae Mon Sep 17 00:00:00 2001 From: Tim Schubert Date: Wed, 7 Jun 2023 11:04:18 +0200 Subject: [PATCH 66/73] Revert "Add armv7a-none-eabi target" This reverts commit c5a119f4dfe8861e072ac0c945b25486c65b404e. --- flake.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/flake.nix b/flake.nix index 79a7e3b..f7b0001 100644 --- a/flake.nix +++ b/flake.nix @@ -21,7 +21,6 @@ stable.cargo stable.rustc stable.rustfmt - targets.armv7a-none-eabi.stable.rust-std ]; naersk-lib = (naersk.lib."${system}".override { cargo = rust-toolchain; From 19e029f896016fd54e9320f28cc50ef667a5fd3e Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 13:14:55 +0200 Subject: [PATCH 67/73] Add armv7a-none-eabi to nix flake --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index f7b0001..79a7e3b 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,7 @@ stable.cargo stable.rustc stable.rustfmt + targets.armv7a-none-eabi.stable.rust-std ]; naersk-lib = (naersk.lib."${system}".override { cargo = rust-toolchain; From 6a2b9f8b1034d9c5cef388a049b3cdfce01e0214 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 13:15:25 +0200 Subject: [PATCH 68/73] fix nix flake --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 79a7e3b..e866ee4 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ let pkgs = import nixpkgs { inherit system; }; rust-toolchain = with fenix.packages.${system}; combine [ - rust-analyzer + stable.rust-analyzer stable.cargo stable.rustc stable.rustfmt From 09cd7c979523de28266e0d8ea53f37d53a6b5ee6 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 13:18:14 +0200 Subject: [PATCH 69/73] fix unused import --- opentaws/src/aircraft_state.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 02267ac..386c899 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -240,7 +240,9 @@ impl AircraftState { } fn wrap_position(lat: Angle, lon: Angle) -> (Angle, Angle) { + #[allow(unused_imports)] use ::uom::num_traits::Float; + let quadrant = ((lat.abs() / *QUARTER_REVOLUTION) .get::() .floor() as i64) From d4880143841886a2e7788c96925fed11d91accff Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 13:19:34 +0200 Subject: [PATCH 70/73] fix cargo resolver warning --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 8180e92..ad84fbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,3 @@ [workspace] +resolver = "2" members = ["opentaws", "taws_minimal"] From 7cb3206343ea336337047f49594f969fc4179a22 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 14:32:03 +0200 Subject: [PATCH 71/73] feat: serde support for AircraftState and Alert --- Cargo.lock | 5 +++++ opentaws/Cargo.toml | 10 ++++++++++ opentaws/src/aircraft_state.rs | 2 ++ opentaws/src/alerts.rs | 7 +++++++ opentaws/src/class_c.rs | 4 ++-- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2471655..c077fbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,6 +519,7 @@ dependencies = [ "atomic-polyfill", "hash32", "rustc_version", + "serde", "spin 0.9.8", "stable_deref_trait", ] @@ -668,6 +669,7 @@ dependencies = [ "num-complex", "num-rational", "num-traits", + "serde", "simba", "typenum", ] @@ -700,6 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" dependencies = [ "num-traits", + "serde", ] [[package]] @@ -746,6 +749,7 @@ dependencies = [ "heapless", "lazy_static", "nalgebra", + "serde", "uom", ] @@ -1229,6 +1233,7 @@ version = "0.35.0" source = "git+https://github.com/moritz-meier/uom.git?branch=fix-missing-libm#4afd75d1a46b7256db04e9551897a1e0219df2ef" dependencies = [ "num-traits", + "serde", "typenum", ] diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 4c02e69..7b6565d 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -22,6 +22,13 @@ is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS maintenance = { status = "actively-developed" } [features] +default = ["use-serde"] +use-serde = [ + "dep:serde", + "heapless/serde", + "nalgebra/serde-serialize-no-std", + "uom/use_serde", +] [dependencies] lazy_static = { version = "1", default-features = false, features = [ @@ -29,6 +36,9 @@ lazy_static = { version = "1", default-features = false, features = [ ] } heapless = { git = "https://github.com/japaric/heapless.git" } nalgebra = { version = "0.32.2", default-features = false, features = ["libm"] } +serde = { version = "*", optional = true, default-features = false, features = [ + "derive", +] } uom = { git = "https://github.com/moritz-meier/uom.git", branch = "fix-missing-libm", default-features = false, features = [ "f64", "si", diff --git a/opentaws/src/aircraft_state.rs b/opentaws/src/aircraft_state.rs index 386c899..3d0a88d 100644 --- a/opentaws/src/aircraft_state.rs +++ b/opentaws/src/aircraft_state.rs @@ -31,6 +31,7 @@ pub type NormalizedAircraftState = AircraftState; /// Represents the current state of an aircraft #[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] pub struct AircraftState { /// Time when this aircraft state was emitted timestamp: Time, @@ -340,6 +341,7 @@ AircrafState: {{ /// Represents a flight segment #[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] pub enum FlightSegment { /// The aircraft is in cruise flight situation Cruise, diff --git a/opentaws/src/alerts.rs b/opentaws/src/alerts.rs index 28e60aa..f3eefb3 100644 --- a/opentaws/src/alerts.rs +++ b/opentaws/src/alerts.rs @@ -1,12 +1,16 @@ use core::hash::Hash; use heapless::FnvIndexMap; +#[cfg(feature = "use-serde")] +use serde::{Deserialize, Serialize}; + use crate::{ prelude::*, TawsAlertSourcePrioritization, TawsAlertsPrioritizationExt, TawsPrioritizedAlerts, }; /// TAWS Alert levels #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))] pub enum AlertLevel { /// The level or category of alert for conditions that require immediate flight crew awareness /// and immediate flight crew response. @@ -23,6 +27,7 @@ pub enum AlertLevel { /// Represents a TAWS alert #[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))] pub struct Alert { /// The source resp. the TAWS functionallity which emitted this alert pub source: AlertSource, @@ -67,6 +72,7 @@ impl From> for (AlertSource, Al /// Represents a set of [Alerts](Alert) by their [AlertSource](Alert::AlertSource) #[derive(Debug)] +//#[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))] pub struct Alerts where Alert::AlertSource: Hash, @@ -201,6 +207,7 @@ mod tests { use super::*; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] + #[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))] enum TestClass { A, B, diff --git a/opentaws/src/class_c.rs b/opentaws/src/class_c.rs index f40a835..d007e05 100644 --- a/opentaws/src/class_c.rs +++ b/opentaws/src/class_c.rs @@ -6,12 +6,12 @@ mod pda; use core::{fmt::Display, slice::Iter}; -use crate::{alerts::Alert, TawsAlertSourcePrioritization}; +use crate::{alerts::Alert, prelude::*, TawsAlertSourcePrioritization}; -use crate::prelude::*; pub use {ffac::*, /*flta::*,*/ mode1::*, mode3::*, pda::*}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +#[cfg_attr(feature = "use-serde", derive(serde::Serialize, serde::Deserialize))] #[allow(non_camel_case_types)] pub enum ClassC_Source { Ffac, From 540e5dff20c23ceb523fa18607a3d143c63c9e2e Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 22 Sep 2023 14:42:58 +0200 Subject: [PATCH 72/73] remove use-serde from default features --- opentaws/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentaws/Cargo.toml b/opentaws/Cargo.toml index 7b6565d..82f0245 100644 --- a/opentaws/Cargo.toml +++ b/opentaws/Cargo.toml @@ -22,7 +22,7 @@ is-it-maintained-open-issues = { repository = "aeronautical-informatics/openTAWS maintenance = { status = "actively-developed" } [features] -default = ["use-serde"] +default = [] use-serde = [ "dep:serde", "heapless/serde", From cb9006085d68a4deaafdcf9d617beb4626ff91b3 Mon Sep 17 00:00:00 2001 From: Moritz Meier Date: Fri, 27 Oct 2023 10:31:42 +0200 Subject: [PATCH 73/73] fix: update cargo.lock --- Cargo.lock | 242 ++++++++++++++++++++--------------------------------- 1 file changed, 90 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c077fbb..8a6c17c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -27,15 +27,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -51,9 +51,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -76,22 +76,22 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" dependencies = [ "derive_arbitrary", ] [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -128,15 +128,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bstr" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" dependencies = [ "memchr", "serde", @@ -144,24 +144,15 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cfg-if" @@ -171,9 +162,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.4" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" dependencies = [ "clap_builder", "clap_derive", @@ -181,9 +172,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" dependencies = [ "anstream", "anstyle", @@ -194,21 +185,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -302,7 +293,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -336,25 +327,14 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fnv" version = "1.0.7" @@ -363,9 +343,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -378,9 +358,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -388,15 +368,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -405,38 +385,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -514,13 +494,11 @@ dependencies = [ [[package]] name = "heapless" version = "0.8.0" -source = "git+https://github.com/japaric/heapless.git#644653bf3b831c6bb4963be2de24804acf5e5001" +source = "git+https://github.com/japaric/heapless.git#90942787f787b1716608f21afd9d61b5023ee2ca" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version", "serde", - "spin 0.9.8", "stable_deref_trait", ] @@ -604,20 +582,20 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linked-hash-map" @@ -627,19 +605,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" - -[[package]] -name = "lock_api" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "log" @@ -649,9 +617,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "minimal-lexical" @@ -728,9 +696,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -806,9 +774,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -863,25 +831,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] @@ -892,26 +860,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -933,12 +892,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "sealed" version = "0.3.0" @@ -963,30 +916,24 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "semver" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" - [[package]] name = "serde" -version = "1.0.188" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1044,15 +991,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1078,9 +1016,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -1158,22 +1096,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]]