From bcc3f5809e1d596934d66349a72179c90e8d0154 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Tue, 4 Mar 2025 00:51:35 +0200 Subject: [PATCH] src -> app; move core libs to tengri --- Cargo.lock | 224 +++-- Cargo.toml | 8 +- {tek => app}/Cargo.toml | 3 +- {tek => app}/examples/arranger.edn | 0 {tek => app}/examples/clip.edn | 0 {tek => app}/examples/mixer.edn | 0 {tek => app}/examples/sampler.edn | 0 {tek => app}/examples/sequencer.edn | 0 {tek => app}/src/arranger.edn | 0 {tek => app}/src/audio.rs | 0 {tek => app}/src/cli.rs | 0 {tek => app}/src/device.rs | 0 {tek => app}/src/keys.edn | 0 {tek => app}/src/keys.rs | 0 {tek => app}/src/keys_clip.edn | 0 {tek => app}/src/keys_clip.rs | 0 {tek => app}/src/keys_ins.rs | 0 {tek => app}/src/keys_mix.edn | 0 {tek => app}/src/keys_outs.rs | 0 {tek => app}/src/keys_scene.edn | 0 {tek => app}/src/keys_scene.rs | 0 {tek => app}/src/keys_track.edn | 0 {tek => app}/src/keys_track.rs | 0 {tek => app}/src/lib.rs | 0 {tek => app}/src/model.rs | 0 {tek => app}/src/model_scene.rs | 0 {tek => app}/src/model_select.rs | 0 {tek => app}/src/model_track.rs | 0 {tek => app}/src/view.rs | 0 {tek => app}/src/view_arranger.edn | 0 {tek => app}/src/view_arranger.rs | 0 {tek => app}/src/view_clock.rs | 0 {tek => app}/src/view_color.rs | 0 {tek => app}/src/view_groovebox.edn | 0 {tek => app}/src/view_iter.rs | 0 {tek => app}/src/view_memo.rs | 0 {tek => app}/src/view_meter.rs | 0 {tek => app}/src/view_sequencer.edn | 0 {tek => app}/src/view_sizes.rs | 0 {tek => app}/src/view_transport.edn | 0 cli/Cargo.toml | 2 +- edn/Cargo.lock | 980 ------------------- edn/Cargo.toml | 17 - edn/README.md | 94 -- edn/proptest-regressions/iter.txt | 7 - edn/proptest-regressions/token.txt | 7 - edn/src/context.rs | 130 --- edn/src/error.rs | 15 - edn/src/iter.rs | 144 --- edn/src/lib.rs | 61 -- edn/src/token.rs | 169 ---- input/Cargo.lock | 7 - input/Cargo.toml | 10 - input/README.md | 16 - input/src/command.rs | 28 - input/src/event_map.rs | 73 -- input/src/input.rs | 75 -- input/src/keymap.rs | 227 ----- input/src/lib.rs | 32 - midi/Cargo.toml | 3 +- output/Cargo.lock | 14 - output/Cargo.toml | 12 - output/README.md | 76 -- output/proptest-regressions/area.txt | 7 - output/proptest-regressions/direction.txt | 7 - output/proptest-regressions/op_transform.txt | 10 - output/src/area.rs | 137 --- output/src/collection.rs | 23 - output/src/coordinate.rs | 31 - output/src/direction.rs | 38 - output/src/lib.rs | 55 -- output/src/measure.rs | 144 --- output/src/op_align.rs | 102 -- output/src/op_bsp.rs | 143 --- output/src/op_cond.rs | 57 -- output/src/op_iter.rs | 77 -- output/src/op_transform.rs | 232 ----- output/src/output.rs | 132 --- output/src/reduce.rs | 93 -- output/src/size.rs | 63 -- output/src/thunk.rs | 50 - output/src/view.rs | 87 -- plugin/Cargo.toml | 3 +- sampler/Cargo.toml | 3 +- time/Cargo.toml | 6 +- tui/Cargo.toml | 17 - tui/README.md | 15 - tui/examples/demo.rs.old | 144 --- tui/examples/edn01.edn | 1 - tui/examples/edn02.edn | 1 - tui/examples/edn03.edn | 1 - tui/examples/edn04.edn | 1 - tui/examples/edn05.edn | 1 - tui/examples/edn06.edn | 1 - tui/examples/edn07.edn | 1 - tui/examples/edn08.edn | 1 - tui/examples/edn09.edn | 1 - tui/examples/edn10.edn | 1 - tui/examples/edn11.edn | 11 - tui/examples/edn12.edn | 11 - tui/examples/edn13.edn | 11 - tui/examples/edn99.edn | 73 -- tui/examples/tui.rs | 66 -- tui/src/lib.rs | 57 -- tui/src/tui_buffer.rs | 39 - tui/src/tui_color.rs | 163 --- tui/src/tui_content.rs | 522 ---------- tui/src/tui_engine.rs | 82 -- tui/src/tui_file.rs | 87 -- tui/src/tui_focus.rs | 306 ------ tui/src/tui_input.rs | 146 --- tui/src/tui_menu.rs | 63 -- tui/src/tui_output.rs | 104 -- 113 files changed, 132 insertions(+), 5729 deletions(-) rename {tek => app}/Cargo.toml (87%) rename {tek => app}/examples/arranger.edn (100%) rename {tek => app}/examples/clip.edn (100%) rename {tek => app}/examples/mixer.edn (100%) rename {tek => app}/examples/sampler.edn (100%) rename {tek => app}/examples/sequencer.edn (100%) rename {tek => app}/src/arranger.edn (100%) rename {tek => app}/src/audio.rs (100%) rename {tek => app}/src/cli.rs (100%) rename {tek => app}/src/device.rs (100%) rename {tek => app}/src/keys.edn (100%) rename {tek => app}/src/keys.rs (100%) rename {tek => app}/src/keys_clip.edn (100%) rename {tek => app}/src/keys_clip.rs (100%) rename {tek => app}/src/keys_ins.rs (100%) rename {tek => app}/src/keys_mix.edn (100%) rename {tek => app}/src/keys_outs.rs (100%) rename {tek => app}/src/keys_scene.edn (100%) rename {tek => app}/src/keys_scene.rs (100%) rename {tek => app}/src/keys_track.edn (100%) rename {tek => app}/src/keys_track.rs (100%) rename {tek => app}/src/lib.rs (100%) rename {tek => app}/src/model.rs (100%) rename {tek => app}/src/model_scene.rs (100%) rename {tek => app}/src/model_select.rs (100%) rename {tek => app}/src/model_track.rs (100%) rename {tek => app}/src/view.rs (100%) rename {tek => app}/src/view_arranger.edn (100%) rename {tek => app}/src/view_arranger.rs (100%) rename {tek => app}/src/view_clock.rs (100%) rename {tek => app}/src/view_color.rs (100%) rename {tek => app}/src/view_groovebox.edn (100%) rename {tek => app}/src/view_iter.rs (100%) rename {tek => app}/src/view_memo.rs (100%) rename {tek => app}/src/view_meter.rs (100%) rename {tek => app}/src/view_sequencer.edn (100%) rename {tek => app}/src/view_sizes.rs (100%) rename {tek => app}/src/view_transport.edn (100%) delete mode 100644 edn/Cargo.lock delete mode 100644 edn/Cargo.toml delete mode 100644 edn/README.md delete mode 100644 edn/proptest-regressions/iter.txt delete mode 100644 edn/proptest-regressions/token.txt delete mode 100644 edn/src/context.rs delete mode 100644 edn/src/error.rs delete mode 100644 edn/src/iter.rs delete mode 100644 edn/src/lib.rs delete mode 100644 edn/src/token.rs delete mode 100644 input/Cargo.lock delete mode 100644 input/Cargo.toml delete mode 100644 input/README.md delete mode 100644 input/src/command.rs delete mode 100644 input/src/event_map.rs delete mode 100644 input/src/input.rs delete mode 100644 input/src/keymap.rs delete mode 100644 input/src/lib.rs delete mode 100644 output/Cargo.lock delete mode 100644 output/Cargo.toml delete mode 100644 output/README.md delete mode 100644 output/proptest-regressions/area.txt delete mode 100644 output/proptest-regressions/direction.txt delete mode 100644 output/proptest-regressions/op_transform.txt delete mode 100644 output/src/area.rs delete mode 100644 output/src/collection.rs delete mode 100644 output/src/coordinate.rs delete mode 100644 output/src/direction.rs delete mode 100644 output/src/lib.rs delete mode 100644 output/src/measure.rs delete mode 100644 output/src/op_align.rs delete mode 100644 output/src/op_bsp.rs delete mode 100644 output/src/op_cond.rs delete mode 100644 output/src/op_iter.rs delete mode 100644 output/src/op_transform.rs delete mode 100644 output/src/output.rs delete mode 100644 output/src/reduce.rs delete mode 100644 output/src/size.rs delete mode 100644 output/src/thunk.rs delete mode 100644 output/src/view.rs delete mode 100644 tui/Cargo.toml delete mode 100644 tui/README.md delete mode 100644 tui/examples/demo.rs.old delete mode 100644 tui/examples/edn01.edn delete mode 100644 tui/examples/edn02.edn delete mode 100644 tui/examples/edn03.edn delete mode 100644 tui/examples/edn04.edn delete mode 100644 tui/examples/edn05.edn delete mode 100644 tui/examples/edn06.edn delete mode 100644 tui/examples/edn07.edn delete mode 100644 tui/examples/edn08.edn delete mode 100644 tui/examples/edn09.edn delete mode 100644 tui/examples/edn10.edn delete mode 100644 tui/examples/edn11.edn delete mode 100644 tui/examples/edn12.edn delete mode 100644 tui/examples/edn13.edn delete mode 100644 tui/examples/edn99.edn delete mode 100644 tui/examples/tui.rs delete mode 100644 tui/src/lib.rs delete mode 100644 tui/src/tui_buffer.rs delete mode 100644 tui/src/tui_color.rs delete mode 100644 tui/src/tui_content.rs delete mode 100644 tui/src/tui_engine.rs delete mode 100644 tui/src/tui_file.rs delete mode 100644 tui/src/tui_focus.rs delete mode 100644 tui/src/tui_input.rs delete mode 100644 tui/src/tui_menu.rs delete mode 100644 tui/src/tui_output.rs diff --git a/Cargo.lock b/Cargo.lock index dc12edb2..85e1ccb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,15 +148,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "by_address" @@ -166,9 +166,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" [[package]] name = "byteorder" @@ -199,9 +199,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.27" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", @@ -209,9 +209,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", @@ -221,9 +221,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", @@ -237,15 +237,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" -[[package]] -name = "clojure-reader" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4774a73e49ad34674c398196f8bee1aed6187eaa17ce57c17e7703cfd2c05ec6" -dependencies = [ - "ordered-float", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -268,9 +259,9 @@ dependencies = [ [[package]] name = "console" -version = "0.15.10" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", "libc", @@ -315,7 +306,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "crossterm_winapi", "mio", "parking_lot 0.12.3", @@ -371,9 +362,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" [[package]] name = "encode_unicode" @@ -392,9 +383,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -444,7 +435,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets", ] [[package]] @@ -559,7 +562,7 @@ name = "jack" version = "0.13.0" source = "git+https://codeberg.org/unspeaker/rust-jack#a13c1c4d20343e574787a703eaeea7aeda63b084" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "jack-sys", "lazy_static", "libc", @@ -571,7 +574,7 @@ name = "jack-sys" version = "0.5.1" source = "git+https://codeberg.org/unspeaker/rust-jack#a13c1c4d20343e574787a703eaeea7aeda63b084" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "lazy_static", "libc", "libloading", @@ -624,9 +627,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libloading" @@ -690,9 +693,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "lru" @@ -735,9 +738,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] @@ -750,7 +753,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -774,18 +777,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "palette" @@ -855,7 +849,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.8", + "redox_syscall 0.5.10", "smallvec", "windows-targets", ] @@ -910,9 +904,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "ppv-lite86" @@ -925,9 +919,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -940,7 +934,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.8.0", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand", @@ -973,7 +967,7 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi", ] @@ -986,9 +980,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" dependencies = [ "proc-macro2", ] @@ -1020,7 +1014,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -1038,7 +1032,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cassowary", "compact_str", "crossterm", @@ -1055,11 +1049,11 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.3.0" +version = "11.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6928fa44c097620b706542d428957635951bade7143269085389d42c8a4927e" +checksum = "529468c1335c1c03919960dfefdb1b3648858c20d7ec2d0663e728e4a717efbc" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -1093,11 +1087,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -1127,7 +1121,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", @@ -1154,9 +1148,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "scopeguard" @@ -1166,18 +1160,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", @@ -1231,9 +1225,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "static_assertions" @@ -1466,9 +1460,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.96" +version = "2.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" dependencies = [ "proc-macro2", "quote", @@ -1505,21 +1499,19 @@ dependencies = [ [[package]] name = "tek_edn" version = "0.1.0" +source = "git+https://codeberg.org/unspeaker/tengri#5352a9d5484198e35760d62a2cd6ef202990fb2c" dependencies = [ - "clojure-reader", "itertools 0.14.0", "konst", - "proptest", - "tek_tui", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] name = "tek_input" version = "0.2.0" +source = "git+https://codeberg.org/unspeaker/tengri#5352a9d5484198e35760d62a2cd6ef202990fb2c" dependencies = [ "tek_edn", - "tek_tui", ] [[package]] @@ -1543,11 +1535,9 @@ dependencies = [ [[package]] name = "tek_output" version = "0.2.0" +source = "git+https://codeberg.org/unspeaker/tengri#5352a9d5484198e35760d62a2cd6ef202990fb2c" dependencies = [ - "proptest", - "proptest-derive", "tek_edn", - "tek_tui", ] [[package]] @@ -1587,28 +1577,30 @@ dependencies = [ [[package]] name = "tek_tui" version = "0.2.0" +source = "git+https://codeberg.org/unspeaker/tengri#5352a9d5484198e35760d62a2cd6ef202990fb2c" dependencies = [ + "atomic_float", "better-panic", "crossterm", "konst", "palette", + "quanta", "rand", "ratatui", "tek_edn", "tek_input", "tek_output", - "tek_time", ] [[package]] name = "tempfile" -version = "3.15.0" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", - "getrandom", + "getrandom 0.3.1", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1625,11 +1617,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -1645,9 +1637,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -1656,9 +1648,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -1677,9 +1669,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -1711,9 +1703,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-segmentation" @@ -1752,18 +1744,18 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.12.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" +checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" dependencies = [ - "getrandom", + "getrandom 0.3.1", ] [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -1774,6 +1766,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -1960,13 +1961,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.24" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 7538474b..9ea6f4e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,13 @@ [workspace] resolver = "2" members = [ + "./app", "./cli", - "./edn", - "./input", "./jack", "./midi", - "./output", "./plugin", "./sampler", - "./tek", - "./time", - "./tui" + "./time" ] [profile.release] diff --git a/tek/Cargo.toml b/app/Cargo.toml similarity index 87% rename from tek/Cargo.toml rename to app/Cargo.toml index a7956b33..c6fa9de6 100644 --- a/tek/Cargo.toml +++ b/app/Cargo.toml @@ -4,7 +4,8 @@ edition = "2021" version = "0.2.0" [dependencies] -tek_tui = { path = "../tui" } +tek_tui = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } + tek_jack = { path = "../jack" } tek_time = { path = "../time" } tek_midi = { path = "../midi" } diff --git a/tek/examples/arranger.edn b/app/examples/arranger.edn similarity index 100% rename from tek/examples/arranger.edn rename to app/examples/arranger.edn diff --git a/tek/examples/clip.edn b/app/examples/clip.edn similarity index 100% rename from tek/examples/clip.edn rename to app/examples/clip.edn diff --git a/tek/examples/mixer.edn b/app/examples/mixer.edn similarity index 100% rename from tek/examples/mixer.edn rename to app/examples/mixer.edn diff --git a/tek/examples/sampler.edn b/app/examples/sampler.edn similarity index 100% rename from tek/examples/sampler.edn rename to app/examples/sampler.edn diff --git a/tek/examples/sequencer.edn b/app/examples/sequencer.edn similarity index 100% rename from tek/examples/sequencer.edn rename to app/examples/sequencer.edn diff --git a/tek/src/arranger.edn b/app/src/arranger.edn similarity index 100% rename from tek/src/arranger.edn rename to app/src/arranger.edn diff --git a/tek/src/audio.rs b/app/src/audio.rs similarity index 100% rename from tek/src/audio.rs rename to app/src/audio.rs diff --git a/tek/src/cli.rs b/app/src/cli.rs similarity index 100% rename from tek/src/cli.rs rename to app/src/cli.rs diff --git a/tek/src/device.rs b/app/src/device.rs similarity index 100% rename from tek/src/device.rs rename to app/src/device.rs diff --git a/tek/src/keys.edn b/app/src/keys.edn similarity index 100% rename from tek/src/keys.edn rename to app/src/keys.edn diff --git a/tek/src/keys.rs b/app/src/keys.rs similarity index 100% rename from tek/src/keys.rs rename to app/src/keys.rs diff --git a/tek/src/keys_clip.edn b/app/src/keys_clip.edn similarity index 100% rename from tek/src/keys_clip.edn rename to app/src/keys_clip.edn diff --git a/tek/src/keys_clip.rs b/app/src/keys_clip.rs similarity index 100% rename from tek/src/keys_clip.rs rename to app/src/keys_clip.rs diff --git a/tek/src/keys_ins.rs b/app/src/keys_ins.rs similarity index 100% rename from tek/src/keys_ins.rs rename to app/src/keys_ins.rs diff --git a/tek/src/keys_mix.edn b/app/src/keys_mix.edn similarity index 100% rename from tek/src/keys_mix.edn rename to app/src/keys_mix.edn diff --git a/tek/src/keys_outs.rs b/app/src/keys_outs.rs similarity index 100% rename from tek/src/keys_outs.rs rename to app/src/keys_outs.rs diff --git a/tek/src/keys_scene.edn b/app/src/keys_scene.edn similarity index 100% rename from tek/src/keys_scene.edn rename to app/src/keys_scene.edn diff --git a/tek/src/keys_scene.rs b/app/src/keys_scene.rs similarity index 100% rename from tek/src/keys_scene.rs rename to app/src/keys_scene.rs diff --git a/tek/src/keys_track.edn b/app/src/keys_track.edn similarity index 100% rename from tek/src/keys_track.edn rename to app/src/keys_track.edn diff --git a/tek/src/keys_track.rs b/app/src/keys_track.rs similarity index 100% rename from tek/src/keys_track.rs rename to app/src/keys_track.rs diff --git a/tek/src/lib.rs b/app/src/lib.rs similarity index 100% rename from tek/src/lib.rs rename to app/src/lib.rs diff --git a/tek/src/model.rs b/app/src/model.rs similarity index 100% rename from tek/src/model.rs rename to app/src/model.rs diff --git a/tek/src/model_scene.rs b/app/src/model_scene.rs similarity index 100% rename from tek/src/model_scene.rs rename to app/src/model_scene.rs diff --git a/tek/src/model_select.rs b/app/src/model_select.rs similarity index 100% rename from tek/src/model_select.rs rename to app/src/model_select.rs diff --git a/tek/src/model_track.rs b/app/src/model_track.rs similarity index 100% rename from tek/src/model_track.rs rename to app/src/model_track.rs diff --git a/tek/src/view.rs b/app/src/view.rs similarity index 100% rename from tek/src/view.rs rename to app/src/view.rs diff --git a/tek/src/view_arranger.edn b/app/src/view_arranger.edn similarity index 100% rename from tek/src/view_arranger.edn rename to app/src/view_arranger.edn diff --git a/tek/src/view_arranger.rs b/app/src/view_arranger.rs similarity index 100% rename from tek/src/view_arranger.rs rename to app/src/view_arranger.rs diff --git a/tek/src/view_clock.rs b/app/src/view_clock.rs similarity index 100% rename from tek/src/view_clock.rs rename to app/src/view_clock.rs diff --git a/tek/src/view_color.rs b/app/src/view_color.rs similarity index 100% rename from tek/src/view_color.rs rename to app/src/view_color.rs diff --git a/tek/src/view_groovebox.edn b/app/src/view_groovebox.edn similarity index 100% rename from tek/src/view_groovebox.edn rename to app/src/view_groovebox.edn diff --git a/tek/src/view_iter.rs b/app/src/view_iter.rs similarity index 100% rename from tek/src/view_iter.rs rename to app/src/view_iter.rs diff --git a/tek/src/view_memo.rs b/app/src/view_memo.rs similarity index 100% rename from tek/src/view_memo.rs rename to app/src/view_memo.rs diff --git a/tek/src/view_meter.rs b/app/src/view_meter.rs similarity index 100% rename from tek/src/view_meter.rs rename to app/src/view_meter.rs diff --git a/tek/src/view_sequencer.edn b/app/src/view_sequencer.edn similarity index 100% rename from tek/src/view_sequencer.edn rename to app/src/view_sequencer.edn diff --git a/tek/src/view_sizes.rs b/app/src/view_sizes.rs similarity index 100% rename from tek/src/view_sizes.rs rename to app/src/view_sizes.rs diff --git a/tek/src/view_transport.edn b/app/src/view_transport.edn similarity index 100% rename from tek/src/view_transport.edn rename to app/src/view_transport.edn diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6f5b82e8..3ca74edf 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -4,7 +4,7 @@ edition = "2021" version = "0.2.0" [dependencies] -tek = { path = "../tek" } +tek = { path = "../app" } clap = { version = "4.5.4", features = [ "derive" ] } [[bin]] diff --git a/edn/Cargo.lock b/edn/Cargo.lock deleted file mode 100644 index 73059751..00000000 --- a/edn/Cargo.lock +++ /dev/null @@ -1,980 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "better-panic" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa9e1d11a268684cbd90ed36370d7577afb6c62d912ddff5c15fc34343e5036" -dependencies = [ - "backtrace", - "console", -] - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "by_address" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - -[[package]] -name = "castaway" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" -dependencies = [ - "rustversion", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clojure-reader" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edf141eea627c101a97509266bc9f6ba8cd408618f5e2ac4a0cb6b64b1d4ea8" -dependencies = [ - "ordered-float", -] - -[[package]] -name = "compact_str" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", -] - -[[package]] -name = "console" -version = "0.15.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "windows-sys 0.59.0", -] - -[[package]] -name = "const_panic" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53857514f72ee4a2b583de67401e3ff63a5472ca4acf289d09a9ea7636dfec17" - -[[package]] -name = "crossterm" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" -dependencies = [ - "bitflags", - "crossterm_winapi", - "mio", - "parking_lot", - "rustix", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fast-srgb8" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - -[[package]] -name = "instability" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894813a444908c0c8c0e221b041771d107c4a21de1d317dc49bcc66e3c9e5b3f" -dependencies = [ - "darling", - "indoc", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "konst" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4381b9b00c55f251f2ebe9473aef7c117e96828def1a7cb3bd3f0f903c6894e9" -dependencies = [ - "const_panic", - "konst_kernel", - "konst_proc_macros", - "typewit", -] - -[[package]] -name = "konst_kernel" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c" -dependencies = [ - "typewit", -] - -[[package]] -name = "konst_proc_macros" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00af7901ba50898c9e545c24d5c580c96a982298134e8037d8978b6594782c07" - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miniz_oxide" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "palette" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" -dependencies = [ - "approx", - "fast-srgb8", - "palette_derive", - "phf", - "rand", -] - -[[package]] -name = "palette_derive" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" -dependencies = [ - "by_address", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ratatui" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" -dependencies = [ - "bitflags", - "cassowary", - "compact_str", - "crossterm", - "indoc", - "instability", - "itertools 0.13.0", - "lru", - "paste", - "strum", - "unicode-segmentation", - "unicode-truncate", - "unicode-width 0.2.0", -] - -[[package]] -name = "redox_syscall" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustix" -version = "0.38.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustversion" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tek_edn" -version = "0.1.0" -dependencies = [ - "clojure-reader", - "itertools 0.14.0", - "konst", - "tek_tui", -] - -[[package]] -name = "tek_input" -version = "0.2.0" - -[[package]] -name = "tek_output" -version = "0.2.0" -dependencies = [ - "tek_edn", -] - -[[package]] -name = "tek_tui" -version = "0.2.0" -dependencies = [ - "better-panic", - "crossterm", - "palette", - "rand", - "ratatui", - "tek_edn", - "tek_input", - "tek_output", -] - -[[package]] -name = "typewit" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" -dependencies = [ - "typewit_proc_macros", -] - -[[package]] -name = "typewit_proc_macros" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" - -[[package]] -name = "unicode-ident" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-truncate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" -dependencies = [ - "itertools 0.13.0", - "unicode-segmentation", - "unicode-width 0.1.14", -] - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -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.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/edn/Cargo.toml b/edn/Cargo.toml deleted file mode 100644 index c064cfb1..00000000 --- a/edn/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "tek_edn" -edition = "2021" -version = "0.1.0" - -[dependencies] -clojure-reader = "0.3.0" -konst = { version = "0.3.16", features = [ "rust_1_83" ] } -itertools = "0.14.0" -thiserror = "2.0" - -[features] -default = [] - -[dev-dependencies] -tek_tui = { path = "../tui" } -proptest = "^1.6.0" diff --git a/edn/README.md b/edn/README.md deleted file mode 100644 index bffd5f5a..00000000 --- a/edn/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# `ket` - -**ket** is the configuration language of **tek**. -it's based on [edn](https://en.wikipedia.org/wiki/Clojure#Extensible_Data_Notation) -but without all the features. - -## usage - -### with `tek_output` - -this is a `tek_output` view layout defined using ket: - -```edn -(bsp/s (fixed/y 2 :toolbar) - (fill/x (align/c (bsp/w :pool - (bsp/s :outputs (bsp/s :inputs (bsp/s :tracks :scenes))))))) -``` - -### with `tek_input` - -this is a `tek_input` keymap defined using ket: - -```edn -(@u undo 1) -(@shift-u redo 1) -(@e editor show :pool-clip) -(@ctrl-a scene add) -(@ctrl-t track add) -(@tab pool toggle) -``` - -## tokens - -ket has 4 "types", represented by variants of the `Value` enum: - -* `Num` - numeric literal -* `Sym` - textual symbol -* `Key` - textual key -* `Exp` - parenthesized group of tokens - -### numeric literal - -numbers are passed through as is. only non-negative integers are supported. - -```edn -0 -123456 -``` - -### keys - -keys are the names of available operations. they look like this: - -```edn -simple-key -multi-part/key -``` - -keys are implemented by the underlying subsystem: - -* in `tek_output`, keys are names of layout primitives -* in `tek_input`, keys are names of commands - -### symbols - -symbols that start with `:` represent the names of variables -provided by the `Context` trait - such as command parameters, -or entire layout components: - -```edn -:symbol-name -``` - -symbols that start with `@` represent keybindings. -they are parsed in `tek_tui` and look like this: - -```edn -@ctrl-alt-shift-space -``` - -### parenthesized groups - -parenthesized groups represent things like expressions -or configuration statements, and look like this: - -```edn -(some-key :symbol (some/other-key @another-symbol 123) 456) -``` - -## goals - -* [ ] const parse -* [ ] live reload -* [ ] serialize modified code back to original indentation diff --git a/edn/proptest-regressions/iter.txt b/edn/proptest-regressions/iter.txt deleted file mode 100644 index b4d8405a..00000000 --- a/edn/proptest-regressions/iter.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc bbb90b16e6106f17dbb5a4f57594f451360a2ea7e3e20c28adeb8babc98d39df # shrinks to source = "(𰀀" diff --git a/edn/proptest-regressions/token.txt b/edn/proptest-regressions/token.txt deleted file mode 100644 index cc03cf2f..00000000 --- a/edn/proptest-regressions/token.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 5fb814b74ae035bdecb536817090cfb473f0a874e9acf9aaa136a4794cdb367f # shrinks to source = "", start = 10336420442936153584, length = 8110323630773398032 diff --git a/edn/src/context.rs b/edn/src/context.rs deleted file mode 100644 index d7adc789..00000000 --- a/edn/src/context.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::*; -pub trait TryFromAtom<'a, T>: Sized { - fn try_from_expr (_state: &'a T, _iter: TokenIter<'a>) -> Option { None } - fn try_from_atom (state: &'a T, value: Value<'a>) -> Option { - if let Exp(0, iter) = value { return Self::try_from_expr(state, iter) } - None - } -} -pub trait TryIntoAtom: Sized { - fn try_into_atom (&self) -> Option; -} -/// Map EDN tokens to parameters of a given type for a given context -pub trait Context: Sized { - fn get (&self, _atom: &Value) -> Option { - None - } - fn get_or_fail (&self, atom: &Value) -> U { - self.get(atom).expect("no value") - } -} -impl, U> Context for &T { - fn get (&self, atom: &Value) -> Option { - (*self).get(atom) - } - fn get_or_fail (&self, atom: &Value) -> U { - (*self).get_or_fail(atom) - } -} -impl, U> Context for Option { - fn get (&self, atom: &Value) -> Option { - self.as_ref().map(|s|s.get(atom)).flatten() - } - fn get_or_fail (&self, atom: &Value) -> U { - self.as_ref().map(|s|s.get_or_fail(atom)).expect("no provider") - } -} -/// Implement `Context` for a context and type. -#[macro_export] macro_rules! provide { - // Provide a value to the EDN template - ($type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl Context<$type> for $State { - #[allow(unreachable_code)] - fn get (&$self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { $(Sym($pat) => $expr,)* _ => return None }) - } - } - }; - // Provide a value more generically - ($lt:lifetime: $type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl<$lt> Context<$lt, $type> for $State { - #[allow(unreachable_code)] - fn get (&$lt $self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { $(Sym($pat) => $expr,)* _ => return None }) - } - } - }; -} -/// Implement `Context` for a context and numeric type. -/// -/// This enables support for numeric literals. -#[macro_export] macro_rules! provide_num { - // Provide a value that may also be a numeric literal in the EDN, to a generic implementation. - ($type:ty:|$self:ident:<$T:ident:$Trait:path>|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl<$T: $Trait> Context<$type> for $T { - fn get (&$self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { $(Sym($pat) => $expr,)* Num(n) => *n as $type, _ => return None }) - } - } - }; - // Provide a value that may also be a numeric literal in the EDN, to a concrete implementation. - ($type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl Context<$type> for $State { - fn get (&$self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { $(Sym($pat) => $expr,)* Num(n) => *n as $type, _ => return None }) - } - } - }; -} -/// Implement `Context` for a context and the boolean type. -/// -/// This enables support for boolean literals. -#[macro_export] macro_rules! provide_bool { - // Provide a value that may also be a numeric literal in the EDN, to a generic implementation. - ($type:ty:|$self:ident:<$T:ident:$Trait:path>|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl<$T: $Trait> Context<$type> for $T { - fn get (&$self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { - Num(n) => match *n { 0 => false, _ => true }, - Sym(":false") | Sym(":f") => false, - Sym(":true") | Sym(":t") => true, - $(Sym($pat) => $expr,)* - _ => return Context::get(self, atom) - }) - } - } - }; - // Provide a value that may also be a numeric literal in the EDN, to a concrete implementation. - ($type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { - impl Context<$type> for $State { - fn get (&$self, atom: &Value) -> Option<$type> { - use Value::*; - Some(match atom { - Num(n) => match *n { 0 => false, _ => true }, - Sym(":false") | Sym(":f") => false, - Sym(":true") | Sym(":t") => true, - $(Sym($pat) => $expr,)* - _ => return None - }) - } - } - }; -} -#[cfg(test)] #[test] fn test_edn_context () { - struct Test; - provide_bool!(bool: |self: Test|{ - ":provide-bool" => true - }); - let test = Test; - assert_eq!(test.get(&Value::Sym(":false")), Some(false)); - assert_eq!(test.get(&Value::Sym(":true")), Some(true)); - assert_eq!(test.get(&Value::Sym(":provide-bool")), Some(true)); - assert_eq!(test.get(&Value::Sym(":missing-bool")), None); - assert_eq!(test.get(&Value::Num(0)), Some(false)); - assert_eq!(test.get(&Value::Num(1)), Some(true)); -} diff --git a/edn/src/error.rs b/edn/src/error.rs deleted file mode 100644 index 40b687da..00000000 --- a/edn/src/error.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::*; -use thiserror::Error; -pub type ParseResult = Result; -#[derive(Error, Debug, Copy, Clone, PartialEq)] pub enum ParseError { - #[error("parse failed: not implemented")] - Unimplemented, - #[error("parse failed: empty")] - Empty, - #[error("parse failed: incomplete")] - Incomplete, - #[error("parse failed: unexpected character '{0}'")] - Unexpected(char), - #[error("parse failed: error #{0}")] - Code(u8), -} diff --git a/edn/src/iter.rs b/edn/src/iter.rs deleted file mode 100644 index 4ee1dc90..00000000 --- a/edn/src/iter.rs +++ /dev/null @@ -1,144 +0,0 @@ -//! The token iterator [TokenIter] allows you to get the -//! general-purpose syntactic [Token]s represented by the source text. -//! -//! Both iterators are `peek`able: -//! -//! ``` -//! let src = include_str!("../../tek/src/view_arranger.edn"); -//! let mut view = tek_edn::TokenIter::new(src); -//! assert_eq!(view.0.0, src); -//! assert_eq!(view.peek(), view.0.peek()) -//! ``` -use crate::*; -/// Provides a native [Iterator] API over the [ConstIntoIter] [SourceIter] -/// [TokenIter::next] returns just the [Token] and mutates `self`, -/// instead of returning an updated version of the struct as [SourceIter::next] does. -#[derive(Copy, Clone, Debug, Default, PartialEq)] pub struct TokenIter<'a>(pub SourceIter<'a>); -impl<'a> TokenIter<'a> { - pub const fn new (source: &'a str) -> Self { Self(SourceIter::new(source)) } - pub const fn peek (&self) -> Option> { self.0.peek() } -} -impl<'a> Iterator for TokenIter<'a> { - type Item = Token<'a>; - fn next (&mut self) -> Option> { - self.0.next().map(|(item, rest)|{self.0 = rest; item}) - } -} -/// Owns a reference to the source text. -/// [SourceIter::next] emits subsequent pairs of: -/// * a [Token] and -/// * the source text remaining -/// * [ ] TODO: maybe [SourceIter::next] should wrap the remaining source in `Self` ? -#[derive(Copy, Clone, Debug, Default, PartialEq)] pub struct SourceIter<'a>(pub &'a str); -const_iter!(<'a>|self: SourceIter<'a>| => Token<'a> => self.next_mut().map(|(result, _)|result)); -impl<'a> From<&'a str> for SourceIter<'a> {fn from (source: &'a str) -> Self{Self::new(source)}} -impl<'a> SourceIter<'a> { - pub const fn new (source: &'a str) -> Self { Self(source) } - pub const fn chomp (&self, index: usize) -> Self { Self(split_at(self.0, index).1) } - pub const fn next (mut self) -> Option<(Token<'a>, Self)> { Self::next_mut(&mut self) } - pub const fn peek (&self) -> Option> { peek_src(self.0) } - pub const fn next_mut (&mut self) -> Option<(Token<'a>, Self)> { - match self.peek() { - Some(token) => Some((token, self.chomp(token.end()))), - None => None - } - } -} -pub const fn peek_src <'a> (source: &'a str) -> Option> { - let mut token: Token<'a> = Token::new(source, 0, 0, Nil); - iterate!(char_indices(source) => (start, c) => token = match token.value() { - Err(_) => return Some(token), - Nil => match c { - ' '|'\n'|'\r'|'\t' => - token.grow(), - '(' => - Token::new(source, start, 1, Exp(1, TokenIter::new(str_range(source, start, start + 1)))), - ':'|'@' => - Token::new(source, start, 1, Sym(str_range(source, start, start + 1))), - '/'|'a'..='z' => - Token::new(source, start, 1, Key(str_range(source, start, start + 1))), - '0'..='9' => - Token::new(source, start, 1, match to_digit(c) { - Ok(c) => Value::Num(c), - Result::Err(e) => Value::Err(e) - }), - _ => token.error(Unexpected(c)) - }, - Num(n) => match c { - '0'..='9' => token.grow_num(n, c), - ' '|'\n'|'\r'|'\t'|')' => return Some(token), - _ => token.error(Unexpected(c)) - }, - Sym(_) => match c { - 'a'..='z'|'A'..='Z'|'0'..='9'|'-' => token.grow_sym(), - ' '|'\n'|'\r'|'\t'|')' => return Some(token), - _ => token.error(Unexpected(c)) - }, - Key(_) => match c { - 'a'..='z'|'0'..='9'|'-'|'/' => token.grow_key(), - ' '|'\n'|'\r'|'\t'|')' => return Some(token), - _ => token.error(Unexpected(c)) - }, - Exp(depth, _) => match depth { - 0 => return Some(token.grow_exp()), - _ => match c { - ')' => token.grow_out(), - '(' => token.grow_in(), - _ => token.grow_exp(), - } - }, - }); - match token.value() { - Nil => None, - _ => Some(token), - } -} -pub const fn to_number (digits: &str) -> Result { - let mut value = 0; - iterate!(char_indices(digits) => (_, c) => match to_digit(c) { - Ok(digit) => value = 10 * value + digit, - Result::Err(e) => return Result::Err(e) - }); - Ok(value) -} -pub const fn to_digit (c: char) -> Result { - Ok(match c { - '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, - '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, - _ => return Result::Err(Unexpected(c)) - }) -} -#[cfg(test)] mod test_token_iter { - use super::*; - //use proptest::prelude::*; - #[test] fn test_iters () { - let mut iter = crate::SourceIter::new(&":foo :bar"); - let _ = iter.next(); - let mut iter = crate::TokenIter::new(&":foo :bar"); - let _ = iter.next(); - } - #[test] const fn test_const_iters () { - let mut iter = crate::SourceIter::new(&":foo :bar"); - let _ = iter.next(); - } - #[test] fn test_num () { - let digit = to_digit('0'); - let digit = to_digit('x'); - let number = to_number(&"123"); - let number = to_number(&"12asdf3"); - } - //proptest! { - //#[test] fn proptest_source_iter ( - //source in "\\PC*" - //) { - //let mut iter = crate::SourceIter::new(&source); - ////let _ = iter.next(); - //} - //#[test] fn proptest_token_iter ( - //source in "\\PC*" - //) { - //let mut iter = crate::TokenIter::new(&source); - ////let _ = iter.next(); - //} - //} -} diff --git a/edn/src/lib.rs b/edn/src/lib.rs deleted file mode 100644 index 10d60bbc..00000000 --- a/edn/src/lib.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![feature(adt_const_params)] -#![feature(type_alias_impl_trait)] -#![feature(impl_trait_in_fn_trait_return)] -mod error; pub use self::error::*; -mod token; pub use self::token::*; -mod iter; pub use self::iter::*; -mod context; pub use self::context::*; -pub(crate) use self::Value::*; -pub(crate) use self::ParseError::*; -pub(crate) use konst::iter::{ConstIntoIter, IsIteratorKind}; -pub(crate) use konst::string::{split_at, str_range, char_indices}; -pub(crate) use std::error::Error; -pub(crate) use std::fmt::{Debug, Display, Formatter, Result as FormatResult}; -/// Static iteration helper. -#[macro_export] macro_rules! iterate { - ($expr:expr => $arg: pat => $body:expr) => { - let mut iter = $expr; - while let Some(($arg, next)) = iter.next() { - $body; - iter = next; - } - } -} -/// Implement the const iterator pattern. -#[macro_export] macro_rules! const_iter { - ($(<$l:lifetime>)?|$self:ident: $Struct:ty| => $Item:ty => $expr:expr) => { - impl$(<$l>)? Iterator for $Struct { - type Item = $Item; - fn next (&mut $self) -> Option<$Item> { $expr } - } - impl$(<$l>)? ConstIntoIter for $Struct { - type Kind = IsIteratorKind; - type Item = $Item; - type IntoIter = Self; - } - } -} -//#[cfg(test)] #[test] fn test_examples () -> Result<(), ParseError> { - //// Let's pretend to render some view. - //let source = include_str!("../../tek/src/view_arranger.edn"); - //// The token iterator allows you to get the tokens represented by the source text. - //let mut view = TokenIter(source); - //// The token iterator wraps a const token+source iterator. - //assert_eq!(view.0.0, source); - //let mut expr = view.peek(); - //assert_eq!(view.0.0, source); - //assert_eq!(expr, Some(Token { - //source, start: 0, length: source.len() - 1, value: Exp(0, SourceIter(&source[1..])) - //})); - ////panic!("{view:?}"); - ////panic!("{:#?}", expr); - ////for example in [ - ////include_str!("../../tui/examples/edn01.edn"), - ////include_str!("../../tui/examples/edn02.edn"), - ////] { - //////let items = Atom::read_all(example)?; - //////panic!("{layout:?}"); - //////let content = >::from(&layout); - ////} - //Ok(()) -//} diff --git a/edn/src/token.rs b/edn/src/token.rs deleted file mode 100644 index d151d63e..00000000 --- a/edn/src/token.rs +++ /dev/null @@ -1,169 +0,0 @@ -//! [Token]s are parsed substrings with an associated [Value]. -//! -//! * [ ] FIXME: Value may be [Err] which may shadow [Result::Err] -//! * [Value::Exp] wraps an expression depth and a [SourceIter] -//! with the remaining part of the expression. -//! * expression depth other that 0 mean unclosed parenthesis. -//! * closing and unopened parenthesis panics during reading. -//! * [ ] TODO: signed depth might be interesting -//! * [Value::Sym] and [Value::Key] are stringish literals -//! with slightly different parsing rules. -//! * [Value::Num] is an unsigned integer literal. -//!``` -//! use tek_edn::{*, Value::*}; -//! let source = include_str!("../../tek/src/view_arranger.edn"); -//! let mut view = TokenIter::new(source); -//! assert_eq!(view.peek(), Some(Token { -//! source, -//! start: 0, -//! length: source.len(), -//! value: Exp(0, TokenIter::new(&source[1..])) -//! })); -//!``` -use crate::*; -use self::Value::*; -#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct Token<'a> { - pub source: &'a str, - pub start: usize, - pub length: usize, - pub value: Value<'a>, -} -#[derive(Debug, Copy, Clone, Default, PartialEq)] pub enum Value<'a> { - #[default] Nil, - Err(ParseError), - Num(usize), - Sym(&'a str), - Key(&'a str), - Exp(usize, TokenIter<'a>), -} -impl<'a> Token<'a> { - pub const fn new (source: &'a str, start: usize, length: usize, value: Value<'a>) -> Self { - Self { source, start, length, value } - } - pub const fn end (&self) -> usize { - self.start.saturating_add(self.length) - } - pub const fn slice (&'a self) -> &'a str { - self.slice_source(self.source) - //str_range(self.source, self.start, self.end()) - } - pub const fn slice_source <'b> (&'a self, source: &'b str) -> &'b str { - str_range(source, self.start, self.end()) - } - pub const fn slice_source_exp <'b> (&'a self, source: &'b str) -> &'b str { - str_range(source, self.start.saturating_add(1), self.end()) - } - pub const fn value (&self) -> Value { - self.value - } - pub const fn error (self, error: ParseError) -> Self { - Self { value: Value::Err(error), ..self } - } - pub const fn grow (self) -> Self { - Self { length: self.length.saturating_add(1), ..self } - } - pub const fn grow_num (self, m: usize, c: char) -> Self { - match to_digit(c) { - Ok(n) => Self { value: Num(10*m+n), ..self.grow() }, - Result::Err(e) => Self { value: Err(e), ..self.grow() }, - } - } - pub const fn grow_key (self) -> Self { - let mut token = self.grow(); - token.value = Key(token.slice_source(self.source)); - token - } - pub const fn grow_sym (self) -> Self { - let mut token = self.grow(); - token.value = Sym(token.slice_source(self.source)); - token - } - pub const fn grow_exp (self) -> Self { - let mut token = self.grow(); - if let Exp(depth, _) = token.value { - token.value = Exp(depth, TokenIter::new(token.slice_source_exp(self.source))); - } else { - unreachable!() - } - token - } - pub const fn grow_in (self) -> Self { - let mut token = self.grow_exp(); - if let Value::Exp(depth, source) = token.value { - token.value = Value::Exp(depth.saturating_add(1), source) - } else { - unreachable!() - } - token - } - pub const fn grow_out (self) -> Self { - let mut token = self.grow_exp(); - if let Value::Exp(depth, source) = token.value { - if depth > 0 { - token.value = Value::Exp(depth - 1, source) - } else { - return self.error(Unexpected(')')) - } - } else { - unreachable!() - } - token - } -} -#[cfg(test)] mod test_token_prop { - use proptest::prelude::*; - proptest! { - #[test] fn test_token_prop ( - source in "\\PC*", - start in usize::MIN..usize::MAX, - length in usize::MIN..usize::MAX, - ) { - let token = crate::Token { - source: &source, - start, - length, - value: crate::Value::Nil - }; - let _ = token.slice(); - } - } -} -#[cfg(test)] #[test] fn test_token () -> Result<(), Box> { - let source = ":f00"; - let mut token = Token { source, start: 0, length: 1, value: Sym(":") }; - token = token.grow_sym(); - assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") }); - token = token.grow_sym(); - assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") }); - token = token.grow_sym(); - assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") }); - - let src = ""; - assert_eq!(None, SourceIter(src).next()); - - let src = " \n \r \t "; - assert_eq!(None, SourceIter(src).next()); - - let src = "7"; - assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value); - - let src = " 100 "; - assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value); - - let src = " 9a "; - assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value); - - let src = " :123foo "; - assert_eq!(Sym(":123foo"), SourceIter(src).next().unwrap().0.value); - - let src = " \r\r\r\n\n\n@bar456\t\t\t\t\t\t"; - assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value); - - let src = "foo123"; - assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value); - - let src = "foo/bar"; - assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value); - - Ok(()) -} diff --git a/input/Cargo.lock b/input/Cargo.lock deleted file mode 100644 index f9911b02..00000000 --- a/input/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "tek_engine" -version = "0.2.0" diff --git a/input/Cargo.toml b/input/Cargo.toml deleted file mode 100644 index 8022543e..00000000 --- a/input/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "tek_input" -edition = "2021" -version = "0.2.0" - -[dependencies] -tek_edn = { path = "../edn" } - -[dev-dependencies] -tek_tui = { path = "../tui" } diff --git a/input/README.md b/input/README.md deleted file mode 100644 index 6187e5ab..00000000 --- a/input/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# `tek_engine` - -## rendering - -## input handling - -the **input thread** polls for keyboard events -and passes them onto the application's `Handle::handle` method. - -thus, for a type to be a valid application for engine `E`, -it must implement the trait `Handle`, which allows it -to respond to user input. - -this thread has write access to the application state, -and is responsible for mutating it in response to -user activity. diff --git a/input/src/command.rs b/input/src/command.rs deleted file mode 100644 index 23b24640..00000000 --- a/input/src/command.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::*; -#[macro_export] macro_rules! command { - ($(<$($l:lifetime),+>)?|$self:ident:$Command:ty,$state:ident:$State:ty|$handler:expr) => { - impl$(<$($l),+>)? Command<$State> for $Command { - fn execute ($self, $state: &mut $State) -> Perhaps { - Ok($handler) - } - } - }; -} -pub trait Command: Send + Sync + Sized { - fn execute (self, state: &mut S) -> Perhaps; - fn delegate (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps - where Self: Sized - { - Ok(self.execute(state)?.map(wrap)) - } -} -impl> Command for Option { - fn execute (self, _: &mut S) -> Perhaps { - Ok(None) - } - fn delegate (self, _: &mut S, _: impl Fn(Self)->U) -> Perhaps - where Self: Sized - { - Ok(None) - } -} diff --git a/input/src/event_map.rs b/input/src/event_map.rs deleted file mode 100644 index 4a7e2605..00000000 --- a/input/src/event_map.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::*; - -pub struct EventMap<'a, S, I: PartialEq, C> { - pub bindings: &'a [(I, &'a dyn Fn(&S) -> Option)], - pub fallback: Option<&'a dyn Fn(&S, &I) -> Option> -} - -impl<'a, S, I: PartialEq, C> EventMap<'a, S, I, C> { - pub fn handle (&self, state: &S, input: &I) -> Option { - for (binding, handler) in self.bindings.iter() { - if input == binding { - return handler(state) - } - } - if let Some(fallback) = self.fallback { - fallback(state, input) - } else { - None - } - } -} - -#[macro_export] macro_rules! keymap { - ( - $(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty - { $($key:expr => $handler:expr),* $(,)? } $(,)? - ) => { - pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap { - fallback: None, - bindings: &[ $(($key, &|$state|Some($handler)),)* ] - }; - input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?); - }; - ( - $(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty - { $($key:expr => $handler:expr),* $(,)? }, $default:expr - ) => { - pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap { - fallback: Some(&|$state, $input|Some($default)), - bindings: &[ $(($key, &|$state|Some($handler)),)* ] - }; - input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?); - }; -} -#[macro_export] macro_rules! input_to_command { - (<$($l:lifetime),+> $Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => { - impl<$($l),+> InputToCommand<$Input, $State> for $Command { - fn input_to_command ($state: &$State, $input: &$Input) -> Option { - Some($handler) - } - } - }; - ($Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => { - impl InputToCommand<$Input, $State> for $Command { - fn input_to_command ($state: &$State, $input: &$Input) -> Option { - Some($handler) - } - } - } -} - -pub trait InputToCommand: Command + Sized { - fn input_to_command (state: &S, input: &I) -> Option; - fn execute_with_state (state: &mut S, input: &I) -> Perhaps { - Ok(if let Some(command) = Self::input_to_command(state, input) { - let _undo = command.execute(state)?; - Some(true) - } else { - None - }) - } -} - diff --git a/input/src/input.rs b/input/src/input.rs deleted file mode 100644 index c8b59e30..00000000 --- a/input/src/input.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::*; -use std::sync::{Mutex, Arc, RwLock}; - -/// Event source -pub trait Input: Send + Sync + Sized { - /// Type of input event - type Event; - /// Result of handling input - type Handled; // TODO: make this an Option> containing the undo - /// Currently handled event - fn event (&self) -> &Self::Event; - /// Whether component should exit - fn is_done (&self) -> bool; - /// Mark component as done - fn done (&self); -} - -/// Implement the [Handle] trait. -#[macro_export] macro_rules! handle { - (|$self:ident:$Struct:ty,$input:ident|$handler:expr) => { - impl Handle for $Struct { - fn handle (&mut $self, $input: &E) -> Perhaps { - $handler - } - } - }; - ($E:ty: |$self:ident:$Struct:ty,$input:ident|$handler:expr) => { - impl Handle<$E> for $Struct { - fn handle (&mut $self, $input: &$E) -> Perhaps<<$E as Input>::Handled> { - $handler - } - } - } -} - -/// Handle input -pub trait Handle: Send + Sync { - fn handle (&mut self, _input: &E) -> Perhaps { - Ok(None) - } -} -impl> Handle for &mut H { - fn handle (&mut self, context: &E) -> Perhaps { - (*self).handle(context) - } -} -impl> Handle for Option { - fn handle (&mut self, context: &E) -> Perhaps { - if let Some(ref mut handle) = self { - handle.handle(context) - } else { - Ok(None) - } - } -} -impl Handle for Mutex where H: Handle { - fn handle (&mut self, context: &E) -> Perhaps { - self.get_mut().unwrap().handle(context) - } -} -impl Handle for Arc> where H: Handle { - fn handle (&mut self, context: &E) -> Perhaps { - self.lock().unwrap().handle(context) - } -} -impl Handle for RwLock where H: Handle { - fn handle (&mut self, context: &E) -> Perhaps { - self.write().unwrap().handle(context) - } -} -impl Handle for Arc> where H: Handle { - fn handle (&mut self, context: &E) -> Perhaps { - self.write().unwrap().handle(context) - } -} diff --git a/input/src/keymap.rs b/input/src/keymap.rs deleted file mode 100644 index 73b063ea..00000000 --- a/input/src/keymap.rs +++ /dev/null @@ -1,227 +0,0 @@ -use crate::*; -/// [Input] state that can be matched against a [Value]. -pub trait AtomInput: Input { - fn matches_atom (&self, token: &str) -> bool; -} -pub trait KeyMap<'a> { - /// Try to find a command that matches the current input event. - fn command , I: AtomInput> (&'a self, state: &'a S, input: &'a I) - -> Option; -} -impl<'a> KeyMap<'a> for SourceIter<'a> { - fn command , I: AtomInput> (&'a self, state: &'a S, input: &'a I) - -> Option - { - let mut iter = self.clone(); - while let Some((token, rest)) = iter.next() { - iter = rest; - match token { - Token { value: Value::Exp(0, exp_iter), .. } => { - let mut exp_iter = exp_iter.clone(); - match exp_iter.next() { - Some(Token { value: Value::Sym(binding), .. }) => { - if input.matches_atom(binding) { - if let Some(command) = C::try_from_expr(state, exp_iter.clone()) { - return Some(command) - } - } - }, - _ => panic!("invalid config (expected symbol)") - } - }, - _ => panic!("invalid config (expected expression)") - } - } - None - } -} -impl<'a> KeyMap<'a> for TokenIter<'a> { - fn command , I: AtomInput> (&'a self, state: &'a S, input: &'a I) - -> Option - { - let mut iter = self.clone(); - while let Some(next) = iter.next() { - match next { - Token { value: Value::Exp(0, exp_iter), .. } => { - let mut exp_iter = exp_iter.clone(); - match exp_iter.next() { - Some(Token { value: Value::Sym(binding), .. }) => { - if input.matches_atom(binding) { - if let Some(command) = C::try_from_expr(state, exp_iter.clone()) { - return Some(command) - } - } - }, - _ => panic!("invalid config (expected symbol)") - } - }, - _ => panic!("invalid config (expected expression)") - } - } - None - } -} -/// A [Command] that can be constructed from a [Token]. -pub trait AtomCommand<'a, C>: TryFromAtom<'a, C> + Command {} -impl<'a, C, T: TryFromAtom<'a, C> + Command> AtomCommand<'a, C> for T {} -/** Implement `AtomCommand` for given `State` and `Command` */ -#[macro_export] macro_rules! atom_command { - ($Command:ty : |$state:ident:<$State:ident: $Trait:path>| { $(( - // identifier - $key:literal [ - // named parameters - $( - // argument name - $arg:ident - // if type is not provided defaults to Atom - $( - // type:name separator - : - // argument type - $type:ty - )? - ),* - // rest of parameters - $(, ..$rest:ident)? - ] - // bound command: - $command:expr - ))* }) => { - impl<'a, $State: $Trait> TryFromAtom<'a, $State> for $Command { - fn try_from_expr ($state: &$State, iter: TokenIter) -> Option { - let iter = iter.clone(); - match iter.next() { - $(Some(Token { value: Value::Key($key), .. }) => { - let iter = iter.clone(); - $( - let next = iter.next(); - if next.is_none() { panic!("no argument: {}", stringify!($arg)); } - let $arg = next.unwrap(); - $(let $arg: Option<$type> = Context::<$type>::get($state, &$arg.value);)? - )* - $(let $rest = iter.clone();)? - return $command - },)* - _ => None - } - None - } - } - }; - ($Command:ty : |$state:ident:$State:ty| { $(( - // identifier - $key:literal [ - // named parameters - $( - // argument name - $arg:ident - // if type is not provided defaults to Atom - $( - // type:name separator - : - // argument type - $type:ty - )? - ),* - // rest of parameters - $(, ..$rest:ident)? - ] - // bound command: - $command:expr - ))* }) => { - impl<'a> TryFromAtom<'a, $State> for $Command { - fn try_from_expr ($state: &$State, iter: TokenIter) -> Option { - let mut iter = iter.clone(); - match iter.next() { - $(Some(Token { value: Value::Key($key), .. }) => { - let mut iter = iter.clone(); - $( - let next = iter.next(); - if next.is_none() { panic!("no argument: {}", stringify!($arg)); } - let $arg = next.unwrap(); - $(let $arg: Option<$type> = Context::<$type>::get($state, &$arg.value);)? - )* - $(let $rest = iter.clone();)? - return $command - }),* - _ => None - } - } - } - }; - (@bind $state:ident =>$arg:ident ? : $type:ty) => { - let $arg: Option<$type> = Context::<$type>::get($state, $arg); - }; - (@bind $state:ident => $arg:ident : $type:ty) => { - let $arg: $type = Context::<$type>::get_or_fail($state, $arg); - }; -} -//pub struct SourceKeyMap<'a>(&'a str); -//impl<'a> KeyMap for SourceKeyMap<'a> { - //fn command > (&self, state: &S, input: &AtomInput) -> Option { - //todo!(); - //None - //} -//} -//pub struct ParsedKeyMap<'a>(TokensIterator<'a>); -//impl<'a> KeyMap for ParsedKeyMap<'a> { - //fn command > (&self, state: &S, input: &AtomInput) -> Option { - //todo!(); - //None - //} -//} -//pub struct RefKeyMap<'a>(TokensIterator<'a>); -//impl<'a> KeyMap for RefKeyMap<'a> { - //fn command > (&self, state: &S, input: &AtomInput) -> Option { - //todo!(); - ////for token in self.0 { - ////match token?.kind() { - ////TokenKind::Exp => match atoms.as_slice() { - ////[key, command, args @ ..] => match (key.kind(), key.text()) { - ////(TokenKind::Sym, key) => { - ////if input.matches_atom(key) { - ////let command = C::from_atom(state, command, args); - ////if command.is_some() { - ////return command - ////} - ////} - ////}, - ////_ => panic!("invalid config: {item}") - ////}, - ////_ => panic!("invalid config: {item}") - ////} - ////_ => panic!("invalid config: {item}") - ////} - ////} - //None - //} -//} -//pub struct ArcKeyMap(Vec); -//impl KeyMap for ArcKeyMap { - //fn command > (&self, state: &S, input: &AtomInput) -> Option { - //for atom in self.0.iter() { - //match atom { - //ArcAtom::Exp(atoms) => match atoms.as_slice() { - //[key, command, args @ ..] => match (key.kind(), key.text()) { - //(TokenKind::Sym, key) => { - //if input.matches_atom(key) { - //let command = C::from_atom(state, command, args); - //if command.is_some() { - //return command - //} - //} - //}, - //_ => panic!("invalid config: {atom}") - //}, - //_ => panic!("invalid config: {atom}") - //} - //_ => panic!("invalid config: {atom}") - //} - //} - //None - //} -//} -#[cfg(test)] #[test] fn test_atom_keymap () -> Usually<()> { - let keymap = SourceIter::new(""); - Ok(()) -} diff --git a/input/src/lib.rs b/input/src/lib.rs deleted file mode 100644 index c6a0838a..00000000 --- a/input/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![feature(associated_type_defaults)] -mod input; pub use self::input::*; -mod command; pub use self::command::*; -mod keymap; pub use self::keymap::*; -//mod event_map; pub use self::event_map::*; -pub(crate) use ::tek_edn::*; -/// Standard error trait. -pub(crate) use std::error::Error; -/// Standard result type. -#[cfg(test)] pub(crate) type Usually = Result>; -/// Standard optional result type. -pub(crate) type Perhaps = Result, Box>; -#[cfg(test)] #[test] fn test_stub_input () -> Usually<()> { - use crate::*; - struct TestInput(bool); - enum TestEvent { Test1 } - impl Input for TestInput { - type Event = TestEvent; - type Handled = (); - fn event (&self) -> &Self::Event { - &TestEvent::Test1 - } - fn is_done (&self) -> bool { - self.0 - } - fn done (&self) {} - } - let _ = TestInput(true).event(); - assert!(TestInput(true).is_done()); - assert!(!TestInput(false).is_done()); - Ok(()) -} diff --git a/midi/Cargo.toml b/midi/Cargo.toml index cab3b70c..20809419 100644 --- a/midi/Cargo.toml +++ b/midi/Cargo.toml @@ -4,7 +4,8 @@ edition = "2021" version = "0.2.0" [dependencies] -tek_tui = { path = "../tui" } +tek_tui = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } + tek_jack = { path = "../jack" } tek_time = { path = "../time" } diff --git a/output/Cargo.lock b/output/Cargo.lock deleted file mode 100644 index b6f132da..00000000 --- a/output/Cargo.lock +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "tek_engine" -version = "0.2.0" - -[[package]] -name = "tek_layout" -version = "0.2.0" -dependencies = [ - "tek_engine", -] diff --git a/output/Cargo.toml b/output/Cargo.toml deleted file mode 100644 index 3a708adf..00000000 --- a/output/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "tek_output" -edition = "2021" -version = "0.2.0" - -[dependencies] -tek_edn = { path = "../edn" } - -[dev-dependencies] -tek_tui = { path = "../tui" } -proptest = "^1" -proptest-derive = "^0.5.1" diff --git a/output/README.md b/output/README.md deleted file mode 100644 index 4f575b64..00000000 --- a/output/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# `tek_output` - -## free floating layout primitives - -this crate exposes several layout operators -which work entirely in unsigned coordinates -and are generic over `tek_engine::Engine` -and `tek_engine::Content`. chiefly, they -are not dependent on rendering framework. - -|operator|description| -|-|-| -|**`When(x, a)`**|render `a` only when `x == true`| -|**`Either(x, a, b)`**|render `a` when `x == true`, otherwise render `b`| -|**`Map(get_iterator, callback)`**|transform items in uniform way| -|**`Bsp`**|concatenative layout| -|...|...| -|**`Align`**|pin content along axis| -|...|...| -|**`Fill`**|**make content's dimension equal to container's:**| -|`Fill::x(a)`|use container's width for content| -|`Fill::y(a)`|use container's height for content| -|`Fill::xy(a)`|use container's width and height for content| -|**`Fixed`**|**assign fixed dimension to content:**| -|`Fixed::x(w, a)`|use width `w` for content| -|`Fixed::y(w, a)`|use height `w` for content| -|`Fixed::xy(w, h, a)`|use width `w` and height `h` for content| -|**`Expand`/`Shrink`**|**change dimension of content:**| -|`Expand::x(n, a)`/`Shrink::x(n, a)`|increment/decrement width of content area by `n`| -|`Expand::y(n, a)`/`Shrink::y(n, a)`|increment/decrement height of content area by `m`| -|`Expand::xy(n, m, a)`/`Shrink::xy(n, m, a)`|increment/decrement width of content area by `n`, height by `m`| -|**`Min`/`Max`**|**constrain dimension of content:**| -|`Min::x(w, a)`/`Max::x(w, a)`|enforce minimum/maximum width `w` for content| -|`Min::y(h, a)`/`Max::y(h, a)`|enforce minimum/maximum height `h` for content| -|`Min::xy(w, h, a)`/`Max::xy(w, h, a)`|enforce minimum/maximum width `w` and height `h` for content| -|**`Push`/`Pull`**|**move content along axis:**| -|`Push::x(n, a)`/`Pull::x(n, a)`|increment/decrement `x` of content area| -|`Push::y(n, a)`/`Pull::y(n, a)`|increment/decrement `y` of content area| -|`Push::xy(n, m, a)`/`Pull::xy(n, m, a)`|increment/decrement `x` and `y` of content area| - -**todo:** -* sensible `Margin`/`Padding` -* `Reduce` - -## example rendering loop - -the **render thread** continually invokes the -`Content::render` method of the application -to redraw the display. it does this efficiently -by using ratatui's double buffering. - -thus, for a type to be a valid application for engine `E`, -it must implement the trait `Content`, which allows -it to display content to the engine's output. - -the most important thing about the `Content` trait is that -it composes: -* you can implement `Content::content` to build - `Content`s out of other `Content`s -* and/or `Content::area` for custom positioning and sizing, -* and/or `Content::render` for custom rendering - within the given `Content`'s area. - -the manner of output is determined by the -`Engine::Output` type, a mutable pointer to which -is passed to the render method, e.g. in the case of -the `Tui` engine: `fn render(&self, output: &mut TuiOut)` - -you can use `TuiOut::blit` and `TuiOut::place` -to draw at specified coordinates of the display, and/or -directly modify the underlying `ratatui::Buffer` at -`output.buffer` - -rendering is intended to work with read-only access -to the application state. if you really need to update -values during rendering, use interior mutability. diff --git a/output/proptest-regressions/area.txt b/output/proptest-regressions/area.txt deleted file mode 100644 index 1c957a54..00000000 --- a/output/proptest-regressions/area.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc d2cd65ec39a1bf43c14bb2d3196c7e84ba854411360e570f06dd7ede62b0fd61 # shrinks to x = 0, y = 43998, w = 0, h = 43076, a = 0, b = 0 diff --git a/output/proptest-regressions/direction.txt b/output/proptest-regressions/direction.txt deleted file mode 100644 index 76b3facc..00000000 --- a/output/proptest-regressions/direction.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 5b236150b286e479089d5bf6accc8ffbc3c0b0a1f955682af1987f342930d31e # shrinks to x = 0, y = 0, w = 0, h = 0, a = 1 diff --git a/output/proptest-regressions/op_transform.txt b/output/proptest-regressions/op_transform.txt deleted file mode 100644 index 59815360..00000000 --- a/output/proptest-regressions/op_transform.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc b05b448ca4eb29304cae506927639494cae99a9e1ab40c58ac9dcb70d1ea1298 # shrinks to op_x = Some(0), op_y = None, content = "", x = 0, y = 46377, w = 0, h = 38318 -cc efdb7136c68396fa7c632cc6d3b304545ada1ba134269278f890639559a17575 # shrinks to op_x = Some(0), op_y = Some(32768), content = "", x = 0, y = 0, w = 0, h = 0 -cc f6d43c39db04f4c0112fe998ef68cff0a4454cd9791775a3014cc81997fbadf4 # shrinks to op_x = Some(10076), op_y = None, content = "", x = 60498, y = 0, w = 0, h = 0 -cc 3cabc97f3fa3a83fd5f8cf2c619ed213c2be5e9b1cb13e5178bde87dd838e2f4 # shrinks to op_x = Some(3924), op_y = None, content = "", x = 63574, y = 0, w = 0, h = 0 diff --git a/output/src/area.rs b/output/src/area.rs deleted file mode 100644 index 261ba54c..00000000 --- a/output/src/area.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::*; -use std::fmt::Debug; - -pub trait Area: From<[N;4]> + Debug + Copy { - fn x (&self) -> N; - fn y (&self) -> N; - fn w (&self) -> N; - fn h (&self) -> N; - #[inline] fn zero () -> [N;4] { - [N::zero(), N::zero(), N::zero(), N::zero()] - } - #[inline] fn from_position (pos: impl Size) -> [N;4] { - let [x, y] = pos.wh(); - [x, y, 0.into(), 0.into()] - } - #[inline] fn from_size (size: impl Size) -> [N;4] { - let [w, h] = size.wh(); - [0.into(), 0.into(), w, h] - } - #[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> { - if self.w() < w || self.h() < h { - Err(format!("min {w}x{h}").into()) - } else { - Ok(self) - } - } - #[inline] fn xy (&self) -> [N;2] { - [self.x(), self.y()] - } - #[inline] fn wh (&self) -> [N;2] { - [self.w(), self.h()] - } - #[inline] fn xywh (&self) -> [N;4] { - [self.x(), self.y(), self.w(), self.h()] - } - #[inline] fn clip_h (&self, h: N) -> [N;4] { - [self.x(), self.y(), self.w(), self.h().min(h)] - } - #[inline] fn clip_w (&self, w: N) -> [N;4] { - [self.x(), self.y(), self.w().min(w), self.h()] - } - #[inline] fn clip (&self, wh: impl Size) -> [N;4] { - [self.x(), self.y(), wh.w(), wh.h()] - } - #[inline] fn set_w (&self, w: N) -> [N;4] { - [self.x(), self.y(), w, self.h()] - } - #[inline] fn set_h (&self, h: N) -> [N;4] { - [self.x(), self.y(), self.w(), h] - } - #[inline] fn x2 (&self) -> N { - self.x().plus(self.w()) - } - #[inline] fn y2 (&self) -> N { - self.y().plus(self.h()) - } - #[inline] fn lrtb (&self) -> [N;4] { - [self.x(), self.x2(), self.y(), self.y2()] - } - #[inline] fn center (&self) -> [N;2] { - [self.x().plus(self.w()/2.into()), self.y().plus(self.h()/2.into())] - } - #[inline] fn center_x (&self, n: N) -> [N;4] { - let [x, y, w, h] = self.xywh(); - [(x.plus(w / 2.into())).minus(n / 2.into()), y.plus(h / 2.into()), n, 1.into()] - } - #[inline] fn center_y (&self, n: N) -> [N;4] { - let [x, y, w, h] = self.xywh(); - [x.plus(w / 2.into()), (y.plus(h / 2.into())).minus(n / 2.into()), 1.into(), n] - } - #[inline] fn center_xy (&self, [n, m]: [N;2]) -> [N;4] { - let [x, y, w, h] = self.xywh(); - [(x.plus(w / 2.into())).minus(n / 2.into()), (y.plus(h / 2.into())).minus(m / 2.into()), n, m] - } - - #[inline] fn centered (&self) -> [N;2] { - [self.x().minus(self.w()/2.into()), self.y().minus(self.h()/2.into())] - } - - fn iter_x (&self) -> impl Iterator where N: std::iter::Step { - self.x()..(self.x()+self.w()) - } - fn iter_y (&self) -> impl Iterator where N: std::iter::Step { - self.y()..(self.y()+self.h()) - } -} - -impl Area for (N, N, N, N) { - #[inline] fn x (&self) -> N { self.0 } - #[inline] fn y (&self) -> N { self.1 } - #[inline] fn w (&self) -> N { self.2 } - #[inline] fn h (&self) -> N { self.3 } -} - -impl Area for [N;4] { - #[inline] fn x (&self) -> N { self[0] } - #[inline] fn y (&self) -> N { self[1] } - #[inline] fn w (&self) -> N { self[2] } - #[inline] fn h (&self) -> N { self[3] } -} - -#[cfg(test)] mod test_area { - use super::*; - use proptest::prelude::*; - proptest! { - #[test] fn test_area_prop ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let _: [u16;4] = <[u16;4] as Area>::zero(); - let _: [u16;4] = <[u16;4] as Area>::from_position([a, b]); - let _: [u16;4] = <[u16;4] as Area>::from_size([a, b]); - let area: [u16;4] = [x, y, w, h]; - let _ = area.expect_min(a, b); - let _ = area.xy(); - let _ = area.wh(); - let _ = area.xywh(); - let _ = area.clip_h(a); - let _ = area.clip_w(b); - let _ = area.clip([a, b]); - let _ = area.set_w(a); - let _ = area.set_h(b); - let _ = area.x2(); - let _ = area.y2(); - let _ = area.lrtb(); - let _ = area.center(); - let _ = area.center_x(a); - let _ = area.center_y(b); - let _ = area.center_xy([a, b]); - let _ = area.centered(); - } - } -} diff --git a/output/src/collection.rs b/output/src/collection.rs deleted file mode 100644 index 5559afea..00000000 --- a/output/src/collection.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Groupings of elements. -use crate::*; - -/// A function or closure that emits renderables. -pub trait Collector: Send + Sync + Fn(&mut dyn FnMut(&dyn Render)) {} - -/// Any function or closure that emits renderables for the given engine matches [CollectCallback]. -impl Collector for F -where E: Engine, F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render)) {} - -pub trait Render { - fn area (&self, to: E::Area) -> E::Area; - fn render (&self, to: &mut E::Output); -} - -impl> Render for C { - fn area (&self, to: E::Area) -> E::Area { - Content::area(self, to) - } - fn render (&self, to: &mut E::Output) { - Content::render(self, to) - } -} diff --git a/output/src/coordinate.rs b/output/src/coordinate.rs deleted file mode 100644 index 9523fbc7..00000000 --- a/output/src/coordinate.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::fmt::{Debug, Display}; -use std::ops::{Add, Sub, Mul, Div}; - -impl Coordinate for u16 { - #[inline] fn plus (self, other: Self) -> Self { - self.saturating_add(other) - } -} - -/// A linear coordinate. -pub trait Coordinate: Send + Sync + Copy - + Add - + Sub - + Mul - + Div - + Ord + PartialEq + Eq - + Debug + Display + Default - + From + Into - + Into - + Into -{ - #[inline] fn zero () -> Self { 0.into() } - #[inline] fn minus (self, other: Self) -> Self { - if self >= other { - self - other - } else { - 0.into() - } - } - fn plus (self, other: Self) -> Self; -} diff --git a/output/src/direction.rs b/output/src/direction.rs deleted file mode 100644 index afa2139a..00000000 --- a/output/src/direction.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::*; -#[cfg(test)] use proptest_derive::Arbitrary; -/// A cardinal direction. -#[derive(Copy, Clone, PartialEq, Debug)] -#[cfg_attr(test, derive(Arbitrary))] -pub enum Direction { North, South, East, West, Above, Below } -impl Direction { - pub fn split_fixed (self, area: impl Area, a: N) -> ([N;4],[N;4]) { - let [x, y, w, h] = area.xywh(); - match self { - North => ([x, y.plus(h).minus(a), w, a], [x, y, w, h.minus(a)]), - South => ([x, y, w, a], [x, y.plus(a), w, h.minus(a)]), - East => ([x, y, a, h], [x.plus(a), y, w.minus(a), h]), - West => ([x.plus(w).minus(a), y, a, h], [x, y, w.minus(a), h]), - Above | Below => (area.xywh(), area.xywh()) - } - } -} -#[cfg(test)] mod test { - use super::*; - use proptest::prelude::*; - proptest! { - #[test] fn proptest_direction ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - ) { - let _ = d.split_fixed([x, y, w, h], a); - } - } -} diff --git a/output/src/lib.rs b/output/src/lib.rs deleted file mode 100644 index f6353d1e..00000000 --- a/output/src/lib.rs +++ /dev/null @@ -1,55 +0,0 @@ -//#![feature(lazy_type_alias)] -#![feature(step_trait)] -#![feature(type_alias_impl_trait)] -#![feature(impl_trait_in_assoc_type)] -mod direction; pub use self::direction::*; -mod coordinate; pub use self::coordinate::*; -mod size; pub use self::size::*; -mod area; pub use self::area::*; -mod output; pub use self::output::*; -mod measure; pub use self::measure::*; -mod thunk; pub use self::thunk::*; -mod op_cond; pub use self::op_cond::*; -mod op_iter; pub use self::op_iter::*; -mod op_align; pub use self::op_align::*; -mod op_bsp; pub use self::op_bsp::*; -mod op_transform; pub use self::op_transform::*; -mod view; pub use self::view::*; -pub(crate) use std::marker::PhantomData; -pub(crate) use std::error::Error; -pub(crate) use ::tek_edn::*; -/// Standard result type. -pub type Usually = Result>; -/// Standard optional result type. -pub type Perhaps = Result, Box>; -#[cfg(test)] #[test] fn test_stub_output () -> Usually<()> { - use crate::*; - struct TestOutput([u16;4]); - impl Output for TestOutput { - type Unit = u16; - type Size = [u16;2]; - type Area = [u16;4]; - fn area (&self) -> [u16;4] { - self.0 - } - fn area_mut (&mut self) -> &mut [u16;4] { - &mut self.0 - } - fn place (&mut self, _: [u16;4], _: &impl Render) { - () - } - } - impl Content for String { - fn render (&self, to: &mut TestOutput) { - to.area_mut().set_w(self.len() as u16); - } - } - Ok(()) -} -#[cfg(test)] #[test] fn test_dimensions () { - use crate::*; - assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); -} -#[cfg(test)] #[test] fn test_layout () -> Usually<()> { - Ok(()) -} diff --git a/output/src/measure.rs b/output/src/measure.rs deleted file mode 100644 index 784f0a28..00000000 --- a/output/src/measure.rs +++ /dev/null @@ -1,144 +0,0 @@ -use crate::*; -use std::sync::{Arc, atomic::{AtomicUsize, Ordering::Relaxed}}; -//use ratatui::prelude::{Style, Color}; -// TODO: 🡘 🡙 ←🡙→ indicator to expand window when too small -pub trait HasSize { - fn size (&self) -> &Measure; -} -#[macro_export] macro_rules! has_size { - (<$E:ty>|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? HasSize<$E> for $Struct $(<$($L),*$($T),*>)? { - fn size (&$self) -> &Measure<$E> { $cb } - } - } -} -/// A widget that tracks its render width and height -#[derive(Default)] -pub struct Measure { - _engine: PhantomData, - pub x: Arc, - pub y: Arc, -} -impl Content for Measure { - fn render (&self, to: &mut E) { - self.x.store(to.area().w().into(), Relaxed); - self.y.store(to.area().h().into(), Relaxed); - } -} -impl Clone for Measure { - fn clone (&self) -> Self { - Self { - _engine: Default::default(), - x: self.x.clone(), - y: self.y.clone(), - } - } -} -impl std::fmt::Debug for Measure { - fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - f.debug_struct("Measure") - .field("width", &self.x) - .field("height", &self.y) - .finish() - } -} -impl Measure { - pub fn new () -> Self { - Self { - _engine: PhantomData::default(), - x: Arc::new(0.into()), - y: Arc::new(0.into()), - } - } - pub fn set_w (&self, w: impl Into) -> &Self { - self.x.store(w.into(), Relaxed); - self - } - pub fn set_h (&self, h: impl Into) -> &Self { - self.y.store(h.into(), Relaxed); - self - } - pub fn set_wh (&self, w: impl Into, h: impl Into) -> &Self { - self.set_w(w); - self.set_h(h); - self - } - pub fn w (&self) -> usize { - self.x.load(Relaxed) - } - pub fn h (&self) -> usize { - self.y.load(Relaxed) - } - pub fn wh (&self) -> [usize;2] { - [self.w(), self.h()] - } - pub fn format (&self) -> Arc { - format!("{}x{}", self.w(), self.h()).into() - } - pub fn of > (&self, item: T) -> Bsp, T> { - Bsp::b(Fill::xy(self), item) - } -} -//#[cfg(test)] #[test] fn test_measure () { - //use tek_tui::*; - //let size: Measure = Measure::default().set_w(1usize).set_h(1usize).clone(); - //let size: Measure = (&Measure::new().set_wh(2usize, 1usize)).clone(); - //let _ = format!("{:?}", &size); - //let _ = size.wh(); - //let _ = size.format(); - //let _ = size.of(()); -//} - -///// A scrollable area. -//pub struct Scroll(pub F, pub Direction, pub u64, PhantomData) -//where - //E: Output, - //F: Send + Sync + Fn(&mut dyn FnMut(&dyn Content)->Usually<()>)->Usually<()>; - -//pub trait ContentDebug { - //fn debug > (other: W) -> DebugOverlay { - //DebugOverlay(Default::default(), other) - //} -//} - -//impl ContentDebug for E {} - -//impl Render for Measure { - //fn min_size (&self, _: [u16;2]) -> Perhaps<[u16;2]> { - //Ok(Some([0u16.into(), 0u16.into()].into())) - //} - //fn render (&self, to: &mut TuiOut) -> Usually<()> { - //self.set_w(to.area().w()); - //self.set_h(to.area().h()); - //Ok(()) - //} -//} - -//impl Measure { - //pub fn debug (&self) -> ShowMeasure { - //ShowMeasure(&self) - //} -//} - -//render!(Tui: |self: ShowMeasure<'a>|render(|to: &mut TuiOut|Ok({ - //let w = self.0.w(); - //let h = self.0.h(); - //to.blit(&format!(" {w} x {h} "), to.area.x(), to.area.y(), Some( - //Style::default().bold().italic().bg(Color::Rgb(255, 0, 255)).fg(Color::Rgb(0,0,0)) - //)) -//}))); - -//pub struct ShowMeasure<'a>(&'a Measure); - -//pub struct DebugOverlay>(PhantomData, pub W); - -//impl> Render for DebugOverlay { - //fn min_size (&self, to: [u16;2]) -> Perhaps<[u16;2]> { - //self.1.min_size(to) - //} - //fn render (&self, to: &mut TuiOut) -> Usually<()> { - //let [x, y, w, h] = to.area(); - //self.1.render(to)?; - //Ok(to.blit(&format!("{w}x{h}+{x}+{y}"), x, y, Some(Style::default().green()))) - //} -//} diff --git a/output/src/op_align.rs b/output/src/op_align.rs deleted file mode 100644 index 8ce3695c..00000000 --- a/output/src/op_align.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Aligns things to the container. Comes with caveats. -//! ``` -//! use ::tek_tui::{*, tek_output::*}; -//! let area: [u16;4] = [10, 10, 20, 20]; -//! fn test (area: [u16;4], item: &impl Content, expected: [u16;4]) { -//! assert_eq!(Content::layout(item, area), expected); -//! assert_eq!(Render::layout(item, area), expected); -//! }; -//! -//! let four = ||Fixed::xy(4, 4, ""); -//! test(area, &Align::nw(four()), [10, 10, 4, 4]); -//! test(area, &Align::n(four()), [18, 10, 4, 4]); -//! test(area, &Align::ne(four()), [26, 10, 4, 4]); -//! test(area, &Align::e(four()), [26, 18, 4, 4]); -//! test(area, &Align::se(four()), [26, 26, 4, 4]); -//! test(area, &Align::s(four()), [18, 26, 4, 4]); -//! test(area, &Align::sw(four()), [10, 26, 4, 4]); -//! test(area, &Align::w(four()), [10, 18, 4, 4]); -//! -//! let two_by_four = ||Fixed::xy(4, 2, ""); -//! test(area, &Align::nw(two_by_four()), [10, 10, 4, 2]); -//! test(area, &Align::n(two_by_four()), [18, 10, 4, 2]); -//! test(area, &Align::ne(two_by_four()), [26, 10, 4, 2]); -//! test(area, &Align::e(two_by_four()), [26, 19, 4, 2]); -//! test(area, &Align::se(two_by_four()), [26, 28, 4, 2]); -//! test(area, &Align::s(two_by_four()), [18, 28, 4, 2]); -//! test(area, &Align::sw(two_by_four()), [10, 28, 4, 2]); -//! test(area, &Align::w(two_by_four()), [10, 19, 4, 2]); -//! ``` -use crate::*; -#[derive(Debug, Copy, Clone, Default)] pub enum Alignment { #[default] Center, X, Y, NW, N, NE, E, SE, S, SW, W } -pub struct Align(Alignment, A); -try_from_expr!(<'a, E>: Align>: |state, iter| - if let Some(Token { value: Value::Key(key), .. }) = iter.peek() { - match key { - "align/c"|"align/x"|"align/y"| - "align/n"|"align/s"|"align/e"|"align/w"| - "align/nw"|"align/sw"|"align/ne"|"align/se" => { - let _ = iter.next().unwrap(); - let c = iter.next().expect("no content specified"); - let c = state.get_content(&c.value).expect("no content provided"); - return Some(match key { - "align/c" => Self::c(c), - "align/x" => Self::x(c), - "align/y" => Self::y(c), - "align/n" => Self::n(c), - "align/s" => Self::s(c), - "align/e" => Self::e(c), - "align/w" => Self::w(c), - "align/nw" => Self::nw(c), - "align/ne" => Self::ne(c), - "align/sw" => Self::sw(c), - "align/se" => Self::se(c), - _ => unreachable!() - }) - }, - _ => return None - } - }); -impl Align { - #[inline] pub fn c (a: A) -> Self { Self(Alignment::Center, a) } - #[inline] pub fn x (a: A) -> Self { Self(Alignment::X, a) } - #[inline] pub fn y (a: A) -> Self { Self(Alignment::Y, a) } - #[inline] pub fn n (a: A) -> Self { Self(Alignment::N, a) } - #[inline] pub fn s (a: A) -> Self { Self(Alignment::S, a) } - #[inline] pub fn e (a: A) -> Self { Self(Alignment::E, a) } - #[inline] pub fn w (a: A) -> Self { Self(Alignment::W, a) } - #[inline] pub fn nw (a: A) -> Self { Self(Alignment::NW, a) } - #[inline] pub fn sw (a: A) -> Self { Self(Alignment::SW, a) } - #[inline] pub fn ne (a: A) -> Self { Self(Alignment::NE, a) } - #[inline] pub fn se (a: A) -> Self { Self(Alignment::SE, a) } -} -impl> Content for Align { - fn content (&self) -> impl Render { - &self.1 - } - fn layout (&self, on: E::Area) -> E::Area { - use Alignment::*; - let it = Render::layout(&self.content(), on).xywh(); - let cx = on.x()+(on.w().minus(it.w())/2.into()); - let cy = on.y()+(on.h().minus(it.h())/2.into()); - let fx = (on.x()+on.w()).minus(it.w()); - let fy = (on.y()+on.h()).minus(it.h()); - let [x, y] = match self.0 { - Center => [cx, cy], - X => [cx, it.y()], - Y => [it.x(), cy], - NW => [on.x(), on.y()], - N => [cx, on.y()], - NE => [fx, on.y()], - W => [on.x(), cy], - E => [fx, cy], - SW => [on.x(), fy], - S => [cx, fy], - SE => [fx, fy], - }.into(); - [x, y, it.w(), it.h()].into() - } - fn render (&self, to: &mut E) { - to.place(Content::layout(self, to.area()), &self.content()) - } -} diff --git a/output/src/op_bsp.rs b/output/src/op_bsp.rs deleted file mode 100644 index 5846750e..00000000 --- a/output/src/op_bsp.rs +++ /dev/null @@ -1,143 +0,0 @@ -use crate::*; -pub use Direction::*; -/// A split or layer. -pub struct Bsp(Direction, X, Y); -impl, B: Content> Content for Bsp { - fn layout (&self, outer: E::Area) -> E::Area { - let [_, _, c] = self.areas(outer); - c - } - fn render (&self, to: &mut E) { - let [area_a, area_b, _] = self.areas(to.area()); - let (a, b) = self.contents(); - match self.0 { - Below => { to.place(area_a, a); to.place(area_b, b); }, - _ => { to.place(area_b, b); to.place(area_a, a); } - } - } -} -try_from_expr!(<'a, E>: Bsp, RenderBox<'a, E>>: |state, iter| { - if let Some(Token { value: Value::Key(key), .. }) = iter.peek() { - match key { - "bsp/n"|"bsp/s"|"bsp/e"|"bsp/w"|"bsp/a"|"bsp/b" => { - let _ = iter.next().unwrap(); - let c1 = iter.next().expect("no content1 specified"); - let c2 = iter.next().expect("no content2 specified"); - let c1 = state.get_content(&c1.value).expect("no content1 provided"); - let c2 = state.get_content(&c2.value).expect("no content2 provided"); - return Some(match key { - "bsp/n" => Self::n(c1, c2), - "bsp/s" => Self::s(c1, c2), - "bsp/e" => Self::e(c1, c2), - "bsp/w" => Self::w(c1, c2), - "bsp/a" => Self::a(c1, c2), - "bsp/b" => Self::b(c1, c2), - _ => unreachable!(), - }) - }, - _ => return None - } - } -}); -impl Bsp { - #[inline] pub fn n (a: A, b: B) -> Self { Self(North, a, b) } - #[inline] pub fn s (a: A, b: B) -> Self { Self(South, a, b) } - #[inline] pub fn e (a: A, b: B) -> Self { Self(East, a, b) } - #[inline] pub fn w (a: A, b: B) -> Self { Self(West, a, b) } - #[inline] pub fn a (a: A, b: B) -> Self { Self(Above, a, b) } - #[inline] pub fn b (a: A, b: B) -> Self { Self(Below, a, b) } -} -pub trait BspAreas, B: Content> { - fn direction (&self) -> Direction; - fn contents (&self) -> (&A, &B); - fn areas (&self, outer: E::Area) -> [E::Area;3] { - let direction = self.direction(); - let [x, y, w, h] = outer.xywh(); - let (a, b) = self.contents(); - let [aw, ah] = a.layout(outer).wh(); - let [bw, bh] = b.layout(match direction { - Above | Below => outer, - South => [x, y + ah, w, h.minus(ah)].into(), - North => [x, y, w, h.minus(ah)].into(), - East => [x + aw, y, w.minus(aw), h].into(), - West => [x, y, w.minus(aw), h].into(), - }).wh(); - match direction { - Above | Below => { - let [x, y, w, h] = outer.center_xy([aw.max(bw), ah.max(bh)]); - let a = [(x + w/2.into()).minus(aw/2.into()), (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [(x + w/2.into()).minus(bw/2.into()), (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] - }, - South => { - let [x, y, w, h] = outer.center_xy([aw.max(bw), ah + bh]); - let a = [(x + w/2.into()).minus(aw/2.into()), y, aw, ah]; - let b = [(x + w/2.into()).minus(bw/2.into()), y + ah, bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] - }, - North => { - let [x, y, w, h] = outer.center_xy([aw.max(bw), ah + bh]); - let a = [(x + (w/2.into())).minus(aw/2.into()), y + bh, aw, ah]; - let b = [(x + (w/2.into())).minus(bw/2.into()), y, bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] - }, - East => { - let [x, y, w, h] = outer.center_xy([aw + bw, ah.max(bh)]); - let a = [x, (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [x + aw, (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] - }, - West => { - let [x, y, w, h] = outer.center_xy([aw + bw, ah.max(bh)]); - let a = [x + bw, (y + h/2.into()).minus(ah/2.into()), aw, ah]; - let b = [x, (y + h/2.into()).minus(bh/2.into()), bw, bh]; - [a.into(), b.into(), [x, y, w, h].into()] - }, - } - } -} -impl, B: Content> BspAreas for Bsp { - fn direction (&self) -> Direction { self.0 } - fn contents (&self) -> (&A, &B) { (&self.1, &self.2) } -} -/// Renders multiple things on top of each other, -#[macro_export] macro_rules! lay { - ($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::b(bsp, $expr);)*; bsp }} -} -/// Stack southward. -#[macro_export] macro_rules! col { - ($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::s(bsp, $expr);)*; bsp }}; -} -/// Stack northward. -#[macro_export] macro_rules! col_up { - ($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::n(bsp, $expr);)*; bsp }} -} -/// Stack eastward. -#[macro_export] macro_rules! row { - ($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::e(bsp, $expr);)*; bsp }}; -} -#[cfg(test)] mod test { - use super::*; - use proptest::prelude::*; - proptest! { - #[test] fn proptest_op_bsp ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - a in "\\PC*", - b in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - let bsp = Bsp(d, a, b); - assert_eq!( - Content::layout(&bsp, [x, y, w, h]), - Render::layout(&bsp, [x, y, w, h]), - ); - } - } -} diff --git a/output/src/op_cond.rs b/output/src/op_cond.rs deleted file mode 100644 index 7f5ad976..00000000 --- a/output/src/op_cond.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::*; -/// Show an item only when a condition is true. -pub struct When(pub bool, pub A); -impl When { #[inline] pub fn new (c: bool, a: A) -> Self { Self(c, a) } } -/// Show one item if a condition is true and another if the condition is false -pub struct Either(pub bool, pub A, pub B); -impl Either { #[inline] pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } } -try_from_expr!(<'a, E>: When>: |state, iter| { - if let Some(Token { value: Value::Key("when"), .. }) = iter.peek() { - let _ = iter.next().unwrap(); - let condition = iter.next().expect("no condition specified"); - let content = iter.next().expect("no content specified"); - let condition = state.get(&condition.value).expect("no condition provided"); - let content = state.get_content(&content.value).expect("no content provided"); - return Some(Self(condition, content)) - } -}); -try_from_expr!(<'a, E>: Either, RenderBox<'a, E>>: |state, iter| { - if let Some(Token { value: Value::Key("either"), .. }) = iter.peek() { - let _ = iter.next().unwrap(); - let condition = iter.next().expect("no condition specified"); - let content = iter.next().expect("no content specified"); - let alternate = iter.next().expect("no alternate specified"); - let condition = state.get(&condition.value).expect("no condition provided"); - let content = state.get_content(&content.value).expect("no content provided"); - let alternate = state.get_content(&alternate.value).expect("no alternate provided"); - return Some(Self(condition, content, alternate)) - } -}); -impl> Content for When { - fn layout (&self, to: E::Area) -> E::Area { - let Self(cond, item) = self; - let mut area = E::Area::zero(); - if *cond { - let item_area = item.layout(to); - area[0] = item_area.x(); - area[1] = item_area.y(); - area[2] = item_area.w(); - area[3] = item_area.h(); - } - area.into() - } - fn render (&self, to: &mut E) { - let Self(cond, item) = self; - if *cond { item.render(to) } - } -} -impl, B: Render> Content for Either { - fn layout (&self, to: E::Area) -> E::Area { - let Self(cond, a, b) = self; - if *cond { a.layout(to) } else { b.layout(to) } - } - fn render (&self, to: &mut E) { - let Self(cond, a, b) = self; - if *cond { a.render(to) } else { b.render(to) } - } -} diff --git a/output/src/op_iter.rs b/output/src/op_iter.rs deleted file mode 100644 index f793a628..00000000 --- a/output/src/op_iter.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::*; -#[inline] pub fn map_south( - item_offset: O::Unit, - item_height: O::Unit, - item: impl Content -) -> impl Content { - Push::y(item_offset, Fixed::y(item_height, Fill::x(item))) -} - -#[inline] pub fn map_south_west( - item_offset: O::Unit, - item_height: O::Unit, - item: impl Content -) -> impl Content { - Push::y(item_offset, Align::nw(Fixed::y(item_height, Fill::x(item)))) -} - -#[inline] pub fn map_east( - item_offset: O::Unit, - item_width: O::Unit, - item: impl Content -) -> impl Content { - Push::x(item_offset, Align::w(Fixed::x(item_width, Fill::y(item)))) -} - -pub struct Map<'a, A, B, I, F, G>(pub PhantomData<&'a()>, pub F, pub G) where - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync + 'a, - G: Fn(A, usize)->B + Send + Sync; - -impl<'a, A, B, I, F, G> Map<'a, A, B, I, F, G> where - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync + 'a, - G: Fn(A, usize)->B + Send + Sync -{ - pub fn new (f: F, g: G) -> Self { - Self(Default::default(), f, g) - } -} - -impl<'a, E, A, B, I, F, G> Content for Map<'a, A, B, I, F, G> where - E: Output, - B: Render, - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync + 'a, - G: Fn(A, usize)->B + Send + Sync -{ - fn layout (&self, area: E::Area) -> E::Area { - let Self(_, get_iterator, callback) = self; - let mut index = 0; - let [mut min_x, mut min_y] = area.center(); - let [mut max_x, mut max_y] = area.center(); - for item in get_iterator() { - let [x,y,w,h] = callback(item, index).layout(area).xywh(); - min_x = min_x.min(x.into()); - min_y = min_y.min(y.into()); - max_x = max_x.max((x + w).into()); - max_y = max_y.max((y + h).into()); - index += 1; - } - let w = max_x - min_x; - let h = max_y - min_y; - //[min_x.into(), min_y.into(), w.into(), h.into()].into() - area.center_xy([w.into(), h.into()].into()).into() - } - fn render (&self, to: &mut E) { - let Self(_, get_iterator, callback) = self; - let mut index = 0; - let area = Content::layout(self, to.area()); - for item in get_iterator() { - let item = callback(item, index); - //to.place(area.into(), &item); - to.place(item.layout(area), &item); - index += 1; - } - } -} diff --git a/output/src/op_transform.rs b/output/src/op_transform.rs deleted file mode 100644 index 5900d8cd..00000000 --- a/output/src/op_transform.rs +++ /dev/null @@ -1,232 +0,0 @@ -//! [Content] items that modify the inherent -//! dimensions of their inner [Render]ables. -//! -//! Transform may also react to the [Area] provided. -//! ``` -//! use ::tek_tui::{*, tek_output::*}; -//! let area: [u16;4] = [10, 10, 20, 20]; -//! fn test (area: [u16;4], item: &impl Content, expected: [u16;4]) { -//! assert_eq!(Content::layout(item, area), expected); -//! assert_eq!(Render::layout(item, area), expected); -//! }; -//! test(area, &(), [20, 20, 0, 0]); -//! -//! test(area, &Fill::xy(()), area); -//! test(area, &Fill::x(()), [10, 20, 20, 0]); -//! test(area, &Fill::y(()), [20, 10, 0, 20]); -//! -//! //FIXME:test(area, &Fixed::x(4, ()), [18, 20, 4, 0]); -//! //FIXME:test(area, &Fixed::y(4, ()), [20, 18, 0, 4]); -//! //FIXME:test(area, &Fixed::xy(4, 4, unit), [18, 18, 4, 4]); -//! ``` -use crate::*; -/// Defines an enum that transforms its content -/// along either the X axis, the Y axis, or both. -macro_rules! transform_xy { - ($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$area:expr) => { - pub enum $Enum { X(T), Y(T), XY(T) } - impl $Enum { - #[inline] pub fn x (item: T) -> Self { Self::X(item) } - #[inline] pub fn y (item: T) -> Self { Self::Y(item) } - #[inline] pub fn xy (item: T) -> Self { Self::XY(item) } - } - impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T> - for $Enum> { - fn try_from_expr (state: &'a T, iter: TokenIter<'a>) -> Option { - let mut iter = iter.clone(); - if let Some(Token { value: Value::Key(k), .. }) = iter.peek() { - if k == $x || k == $y || k == $xy { - let _ = iter.next().unwrap(); - let token = iter.next().expect("no content specified"); - let content = state.get_content(&token.value).expect("no content provided"); - return Some(match k { - $x => Self::x(content), - $y => Self::y(content), - $xy => Self::xy(content), - _ => unreachable!() - }) - } - } - None - } - } - impl> Content for $Enum { - fn content (&self) -> impl Render { - match self { - Self::X(item) => item, - Self::Y(item) => item, - Self::XY(item) => item, - } - } - fn layout (&$self, $to: ::Area) -> ::Area { - use $Enum::*; - $area - } - } - } -} - -/// Defines an enum that parametrically transforms its content -/// along either the X axis, the Y axis, or both. -macro_rules! transform_xy_unit { - ($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$layout:expr) => { - pub enum $Enum { X(U, T), Y(U, T), XY(U, U, T), } - impl $Enum { - #[inline] pub fn x (x: U, item: T) -> Self { Self::X(x, item) } - #[inline] pub fn y (y: U, item: T) -> Self { Self::Y(y, item) } - #[inline] pub fn xy (x: U, y: U, item: T) -> Self { Self::XY(x, y, item) } - } - impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T> - for $Enum> { - fn try_from_expr (state: &'a T, iter: TokenIter<'a>) -> Option { - let mut iter = iter.clone(); - if let Some(Token { value: Value::Key(k), .. }) = iter.peek() { - if k == $x || k == $y { - let _ = iter.next().unwrap(); - let u = iter.next().expect("no unit specified"); - let c = iter.next().expect("no content specified"); - let u = state.get(&u.value).expect("no unit provided"); - let c = state.get_content(&c.value).expect("no content provided"); - return Some(match k { - $x => Self::x(u, c), - $y => Self::y(u, c), - _ => unreachable!(), - }) - } else if k == $xy { - let _ = iter.next().unwrap(); - let u = iter.next().expect("no unit specified"); - let v = iter.next().expect("no unit specified"); - let c = iter.next().expect("no content specified"); - let u = state.get(&u.value).expect("no unit provided"); - let v = state.get(&v.value).expect("no unit provided"); - let c = state.get_content(&c.value).expect("no content provided"); - return Some(Self::xy(u, v, c)) - } - } - None - } - } - impl> Content for $Enum { - fn content (&self) -> impl Render { - Some(match self { - Self::X(_, content) => content, - Self::Y(_, content) => content, - Self::XY(_, _, content) => content, - }) - } - fn layout (&$self, $to: E::Area) -> E::Area { - $layout.into() - } - } - impl $Enum { - #[inline] pub fn dx (&self) -> U { - match self { - Self::X(x, _) => *x, Self::Y(_, _) => 0.into(), Self::XY(x, _, _) => *x, - } - } - #[inline] pub fn dy (&self) -> U { - match self { - Self::X(_, _) => 0.into(), Self::Y(y, _) => *y, Self::XY(_, y, _) => *y, - } - } - } - } -} -transform_xy!("fill/x" "fill/y" "fill/xy" |self: Fill, to|{ - let [x0, y0, wmax, hmax] = to.xywh(); - let [x, y, w, h] = self.content().layout(to).xywh(); - match self { - X(_) => [x0, y, wmax, h], - Y(_) => [x, y0, w, hmax], - XY(_) => [x0, y0, wmax, hmax], - }.into() }); -transform_xy_unit!("fixed/x" "fixed/y" "fixed/xy"|self: Fixed, area|{ - let [x, y, w, h] = area.xywh(); - let fixed_area = match self { - Self::X(fw, _) => [x, y, *fw, h], - Self::Y(fh, _) => [x, y, w, *fh], - Self::XY(fw, fh, _) => [x, y, *fw, *fh], - }; - let [x, y, w, h] = Render::layout(&self.content(), fixed_area.into()).xywh(); - let fixed_area = match self { - Self::X(fw, _) => [x, y, *fw, h], - Self::Y(fh, _) => [x, y, w, *fh], - Self::XY(fw, fh, _) => [x, y, *fw, *fh], - }; - fixed_area }); -transform_xy_unit!("min/x" "min/y" "min/xy"|self: Min, area|{ - let area = Render::layout(&self.content(), area); - match self { - Self::X(mw, _) => [area.x(), area.y(), area.w().max(*mw), area.h()], - Self::Y(mh, _) => [area.x(), area.y(), area.w(), area.h().max(*mh)], - Self::XY(mw, mh, _) => [area.x(), area.y(), area.w().max(*mw), area.h().max(*mh)], - }}); -transform_xy_unit!("max/x" "max/y" "max/xy"|self: Max, area|{ - let [x, y, w, h] = area.xywh(); - Render::layout(&self.content(), match self { - Self::X(fw, _) => [x, y, *fw, h], - Self::Y(fh, _) => [x, y, w, *fh], - Self::XY(fw, fh, _) => [x, y, *fw, *fh], - }.into())}); -transform_xy_unit!("shrink/x" "shrink/y" "shrink/xy"|self: Shrink, area|Render::layout( - &self.content(), - [area.x(), area.y(), area.w().minus(self.dx()), area.h().minus(self.dy())].into())); -transform_xy_unit!("expand/x" "expand/y" "expand/xy"|self: Expand, area|Render::layout( - &self.content(), - [area.x(), area.y(), area.w().plus(self.dx()), area.h().plus(self.dy())].into())); -transform_xy_unit!("push/x" "push/y" "push/xy"|self: Push, area|{ - let area = Render::layout(&self.content(), area); - [area.x().plus(self.dx()), area.y().plus(self.dy()), area.w(), area.h()] }); -transform_xy_unit!("pull/x" "pull/y" "pull/xy"|self: Pull, area|{ - let area = Render::layout(&self.content(), area); - [area.x().minus(self.dx()), area.y().minus(self.dy()), area.w(), area.h()] }); -transform_xy_unit!("margin/x" "margin/y" "margin/xy"|self: Margin, area|{ - let area = Render::layout(&self.content(), area); - let dx = self.dx(); - let dy = self.dy(); - [area.x().minus(dx), area.y().minus(dy), area.w().plus(dy.plus(dy)), area.h().plus(dy.plus(dy))] }); -transform_xy_unit!("padding/x" "padding/y" "padding/xy"|self: Padding, area|{ - let area = Render::layout(&self.content(), area); - let dx = self.dx(); - let dy = self.dy(); - [area.x().plus(dx), area.y().plus(dy), area.w().minus(dy.plus(dy)), area.h().minus(dy.plus(dy)), ] }); - -#[cfg(test)] mod test_op_transform { - use super::*; - use proptest::prelude::*; - use proptest::option::of; - macro_rules! test_op_transform { - ($fn:ident, $Op:ident) => { - proptest! { - #[test] fn $fn ( - op_x in of(u16::MIN..u16::MAX), - op_y in of(u16::MIN..u16::MAX), - content in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - if let Some(op) = match (op_x, op_y) { - (Some(x), Some(y)) => Some($Op::xy(x, y, content)), - (Some(x), None) => Some($Op::x(x, content)), - (Some(y), None) => Some($Op::y(y, content)), - _ => None - } { - assert_eq!(Content::layout(&op, [x, y, w, h]), - Render::layout(&op, [x, y, w, h])); - } - } - } - } - } - test_op_transform!(test_op_fixed, Fixed); - test_op_transform!(test_op_min, Min); - test_op_transform!(test_op_max, Max); - test_op_transform!(test_op_push, Push); - test_op_transform!(test_op_pull, Pull); - test_op_transform!(test_op_shrink, Shrink); - test_op_transform!(test_op_expand, Expand); - test_op_transform!(test_op_margin, Margin); - test_op_transform!(test_op_padding, Padding); -} diff --git a/output/src/output.rs b/output/src/output.rs deleted file mode 100644 index e9936064..00000000 --- a/output/src/output.rs +++ /dev/null @@ -1,132 +0,0 @@ -use crate::*; -use std::ops::Deref; -/// Render target. -pub trait Output: Send + Sync + Sized { - /// Unit of length - type Unit: Coordinate; - /// Rectangle without offset - type Size: Size; - /// Rectangle with offset - type Area: Area; - /// Current output area - fn area (&self) -> Self::Area; - /// Mutable pointer to area - fn area_mut (&mut self) -> &mut Self::Area; - /// Render widget in area - fn place (&mut self, area: Self::Area, content: &impl Render); - #[inline] fn x (&self) -> Self::Unit { self.area().x() } - #[inline] fn y (&self) -> Self::Unit { self.area().y() } - #[inline] fn w (&self) -> Self::Unit { self.area().w() } - #[inline] fn h (&self) -> Self::Unit { self.area().h() } - #[inline] fn wh (&self) -> Self::Size { self.area().wh().into() } -} -/// Renderable with dynamic dispatch. -pub trait Render { - /// Compute layout. - fn layout (&self, area: E::Area) -> E::Area; - /// Write data to display. - fn render (&self, output: &mut E); - /// Perform type erasure, turning `self` into an opaque [RenderBox]. - fn boxed <'a> (self) -> RenderBox<'a, E> where Self: Send + Sync + Sized + 'a { - Box::new(self) as RenderBox<'a, E> - } -} -/// Most importantly, every [Content] is also a [Render]. -/// -/// However, the converse does not hold true. -/// Instead, the [Content::content] method returns an -/// opaque [Render] pointer. -impl> Render for C { - fn layout (&self, area: E::Area) -> E::Area { Content::layout(self, area) } - fn render (&self, output: &mut E) { Content::render(self, output) } -} -/// Opaque pointer to a renderable living on the heap. -/// -/// Return this from [Content::content] to use dynamic dispatch. -pub type RenderBox<'a, E> = Box>; -/// You can render from a box. -impl<'a, E: Output> Content for RenderBox<'a, E> { - fn content (&self) -> impl Render { self.deref() } - //fn boxed <'b> (self) -> RenderBox<'b, E> where Self: Sized + 'b { self } -} -/// Opaque pointer to a renderable. -pub type RenderDyn<'a, E> = dyn Render + Send + Sync + 'a; -/// You can render from an opaque pointer. -impl<'a, E: Output> Content for &RenderDyn<'a, E> where Self: Sized { - fn content (&self) -> impl Render { self.deref() } - fn layout (&self, area: E::Area) -> E::Area { Render::layout(self.deref(), area) } - fn render (&self, output: &mut E) { Render::render(self.deref(), output) } -} -/// Composable renderable with static dispatch. -pub trait Content { - /// Return a [Render]able of a specific type. - fn content (&self) -> impl Render { () } - /// Perform layout. By default, delegates to [Self::content]. - fn layout (&self, area: E::Area) -> E::Area { self.content().layout(area) } - /// Draw to output. By default, delegates to [Self::content]. - fn render (&self, output: &mut E) { self.content().render(output) } -} -/// Every pointer to [Content] is a [Content]. -impl> Content for &C { - fn content (&self) -> impl Render { (*self).content() } - fn layout (&self, area: E::Area) -> E::Area { (*self).layout(area) } - fn render (&self, output: &mut E) { (*self).render(output) } -} -/// The platonic ideal unit of [Content]: total emptiness at dead center (e=1vg^sqrt(-1)) -impl Content for () { - fn layout (&self, area: E::Area) -> E::Area { area.center().to_area_pos().into() } - fn render (&self, _: &mut E) {} -} -impl> Content for Option { - fn content (&self) -> impl Render { - self.as_ref() - } - fn layout (&self, area: E::Area) -> E::Area { - self.as_ref() - .map(|content|content.layout(area)) - .unwrap_or([0.into(), 0.into(), 0.into(), 0.into(),].into()) - } - fn render (&self, output: &mut E) { - self.as_ref() - .map(|content|content.render(output)); - } -} -/// Implement [Content] with composable content for a struct. -#[macro_export] macro_rules! content { - // Implement for all [Output]s. - (|$self:ident:$Struct:ty| $content:expr) => { - impl Content for $Struct { - fn content (&$self) -> impl Render { Some($content) } - } - }; - // Implement for specific [Output]. - ($Output:ty:| - $self:ident: - $Struct:ident$(<$($($L:lifetime)? $($T:ident)? $(:$Trait:path)?),+>)? - |$content:expr) => { - impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Output> - for $Struct $(<$($($L)? $($T)?),+>)? { - fn content (&$self) -> impl Render<$Output> { $content } - } - }; -} -/// Implement [Content] with custom rendering for a struct. -#[macro_export] macro_rules! render { - (|$self:ident:$Struct:ident $(< - $($L:lifetime),* $($T:ident $(:$Trait:path)?),* - >)?, $to:ident | $render:expr) => { - impl <$($($L),*)? E: Output, $($T$(:$Trait)?),*> Content - for $Struct $(<$($L),* $($T),*>>)? { - fn render (&$self, $to: &mut E) { $render } - } - }; - ($Output:ty:| - $self:ident: - $Struct:ident $(<$($($L:lifetime)? $($T:ident)? $(:$Trait:path)?),+>)?, $to:ident - |$render:expr) => { - impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Output> - for $Struct $(<$($($L)? $($T)?),+>)? { - fn render (&$self, $to: &mut $Output) { $render } - } - }; -} diff --git a/output/src/reduce.rs b/output/src/reduce.rs deleted file mode 100644 index 55021efa..00000000 --- a/output/src/reduce.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::*; - -pub struct Reduce(pub PhantomData, pub F, pub G) where - A: Send + Sync, B: Send + Sync, - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync, - G: Fn(A, B, usize)->A + Send + Sync; - -impl Reduce where - A: Send + Sync, B: Send + Sync, - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync, - G: Fn(A, B, usize)->A + Send + Sync -{ - pub fn new (f: F, g: G) -> Self { Self(Default::default(), f, g) } -} - -impl Content for Reduce where - A: Send + Sync, B: Send + Sync, - I: Iterator + Send + Sync, - F: Fn() -> I + Send + Sync, - G: Fn(A, B, usize)->A + Send + Sync -{ - fn content (&self) -> impl Render { - } -} - -/* - - //pub fn reduce (iterator: I, callback: F) -> Reduce where - //E: Output, - //I: Iterator + Send + Sync, - //R: Render, - //F: Fn(R, T, usize) -> R + Send + Sync - //{ - //Reduce(Default::default(), iterator, callback) - //} -pub struct Reduce(PhantomData<(E, R)>, I, F) where - E: Output, - I: Iterator + Send + Sync, - R: Render, - F: Fn(R, T, usize) -> R + Send + Sync; -impl Content for Reduce where - E: Output, - I: Iterator + Send + Sync, - R: Render, - F: Fn(R, T, usize) -> R + Send + Sync -{ - fn render (&self, to: &mut E) { - todo!() - } -} -*/ - -//macro_rules! define_ops { - //($Trait:ident<$E:ident:$Output:path> { $( - //$(#[$attr:meta $($attr_args:tt)*])* - //( - //$fn:ident - //$(<$($G:ident$(:$Gen:path)?, )+>)? - //$Op:ident - //($($arg:ident:$Arg:ty),*) - //) - //)* }) => { - //impl<$E: $Output> $Trait for E {} - //pub trait $Trait<$E: $Output> { - //$( - //$(#[$attr $($attr_args)*])* - //fn $fn $(<$($G),+>)? - //($($arg:$Arg),*)-> $Op<$($(, $G)+)?> - //$(where $($G: $($Gen + Send + Sync)?),+)? - //{ $Op($($arg),*) } - //)* - //} - //} -//} - -//define_ops! { - //Layout { - //(when ,> - //When(cond: bool, item: A)) - ///// When `cond` is `true`, render `a`, otherwise render `b`. - //(either , B: Render,> - //Either(cond: bool, a: A, b: B)) - ///// If `opt` is `Some(T)` renders `cb(t)`, otherwise nothing. - //(opt B, B: Render,> - //Opt(option: Option, cb: F)) - ///// Maps items of iterator through callback. - //(map , I: Iterator, F: Fn() -> I, G: Fn(A, usize)->B,> - //Map(get_iterator: F, callback: G)) - //} -//} - diff --git a/output/src/size.rs b/output/src/size.rs deleted file mode 100644 index c0518d86..00000000 --- a/output/src/size.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::*; -use std::fmt::Debug; - -pub trait Size: From<[N;2]> + Debug + Copy { - fn x (&self) -> N; - fn y (&self) -> N; - #[inline] fn w (&self) -> N { self.x() } - #[inline] fn h (&self) -> N { self.y() } - #[inline] fn wh (&self) -> [N;2] { [self.x(), self.y()] } - #[inline] fn clip_w (&self, w: N) -> [N;2] { [self.w().min(w), self.h()] } - #[inline] fn clip_h (&self, h: N) -> [N;2] { [self.w(), self.h().min(h)] } - #[inline] fn expect_min (&self, w: N, h: N) -> Usually<&Self> { - if self.w() < w || self.h() < h { - Err(format!("min {w}x{h}").into()) - } else { - Ok(self) - } - } - #[inline] fn zero () -> [N;2] { - [N::zero(), N::zero()] - } - #[inline] fn to_area_pos (&self) -> [N;4] { - let [x, y] = self.wh(); - [x, y, 0.into(), 0.into()] - } - #[inline] fn to_area_size (&self) -> [N;4] { - let [w, h] = self.wh(); - [0.into(), 0.into(), w, h] - } -} - -impl Size for (N, N) { - #[inline] fn x (&self) -> N { self.0 } - #[inline] fn y (&self) -> N { self.1 } -} - -impl Size for [N;2] { - #[inline] fn x (&self) -> N { self[0] } - #[inline] fn y (&self) -> N { self[1] } -} - -#[cfg(test)] mod test_size { - use super::*; - use proptest::prelude::*; - proptest! { - #[test] fn test_size ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let size = [x, y]; - let _ = size.w(); - let _ = size.h(); - let _ = size.wh(); - let _ = size.clip_w(a); - let _ = size.clip_h(b); - let _ = size.expect_min(a, b); - let _ = size.to_area_pos(); - let _ = size.to_area_size(); - } - } -} diff --git a/output/src/thunk.rs b/output/src/thunk.rs deleted file mode 100644 index 8bcbcaa4..00000000 --- a/output/src/thunk.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::*; -use std::marker::PhantomData; - -/// Lazily-evaluated [Render]able. -pub struct Thunk, F: Fn()->T + Send + Sync>(PhantomData, F); -impl, F: Fn()->T + Send + Sync> Thunk { - pub fn new (thunk: F) -> Self { - Self(Default::default(), thunk) - } -} -impl, F: Fn()->T + Send + Sync> Content for Thunk { - fn content (&self) -> impl Render { (self.1)() } -} - -pub struct ThunkBox<'a, E: Output>(PhantomData, BoxRenderBox<'a, E> + Send + Sync + 'a>); -impl<'a, E: Output> ThunkBox<'a, E> { - pub fn new (thunk: BoxRenderBox<'a, E> + Send + Sync + 'a>) -> Self { - Self(Default::default(), thunk) - } -} -impl<'a, E: Output> Content for ThunkBox<'a, E> { - fn content (&self) -> impl Render { (self.1)() } -} -impl<'a, E: Output, F: Fn()->T + Send + Sync + 'a, T: Render + Send + Sync + 'a> From for ThunkBox<'a, E> { - fn from (f: F) -> Self { - Self(Default::default(), Box::new(move||f().boxed())) - } -} -//impl<'a, E: Output, F: Fn()->Box + 'a> + Send + Sync + 'a> From for ThunkBox<'a, E> { - //fn from (f: F) -> Self { - //Self(Default::default(), Box::new(f)) - //} -//} - -pub struct ThunkRender(PhantomData, F); -impl ThunkRender { - pub fn new (render: F) -> Self { Self(Default::default(), render) } -} -impl Content for ThunkRender { - fn render (&self, to: &mut E) { (self.1)(to) } -} - -pub struct ThunkLayoutE::Area + Send + Sync, F2: Fn(&mut E) + Send + Sync>(PhantomData, F1, F2); -implE::Area + Send + Sync, F2: Fn(&mut E) + Send + Sync> ThunkLayout { - pub fn new (layout: F1, render: F2) -> Self { Self(Default::default(), layout, render) } -} -implE::Area + Send + Sync, F2: Fn(&mut E) + Send + Sync> Content for ThunkLayout { - fn layout (&self, to: E::Area) -> E::Area { (self.1)(to) } - fn render (&self, to: &mut E) { (self.2)(to) } -} diff --git a/output/src/view.rs b/output/src/view.rs deleted file mode 100644 index c199258e..00000000 --- a/output/src/view.rs +++ /dev/null @@ -1,87 +0,0 @@ -use crate::*; -#[macro_export] macro_rules! view { - ($Output:ty: |$self:ident: $State:ty| $expr:expr; { - $($sym:literal => $body:expr),* $(,)? - }) => { - impl Content<$Output> for $State { - fn content (&$self) -> impl Render<$Output> { $expr } - } - impl<'a> ViewContext<'a, $Output> for $State { - fn get_content_sym (&'a $self, value: &Value<'a>) -> Option> { - if let Value::Sym(s) = value { - match *s { - $($sym => Some($body),)* - _ => None - } - } else { - panic!("expected content, got: {value:?}") - } - } - } - } -} - -// An ephemeral wrapper around view state and view description, -// that is meant to be constructed and returned from [Content::content]. -pub struct View<'a, T>(pub &'a T, pub SourceIter<'a>); -impl<'a, O: Output + 'a, T: ViewContext<'a, O>> Content for View<'a, T> { - fn content (&self) -> impl Render { - let iter = self.1.clone(); - while let Some((Token { value, .. }, _)) = iter.next() { - if let Some(content) = self.0.get_content(&value) { - return Some(content) - } - } - return None - } -} -// Provides components to the view. -pub trait ViewContext<'a, E: Output + 'a>: Send + Sync - + Context - + Context - + Context -{ - fn get_content (&'a self, value: &Value<'a>) -> Option> { - match value { - Value::Sym(_) => self.get_content_sym(value), - Value::Exp(_, _) => self.get_content_exp(value), - _ => panic!("only :symbols and (expressions) accepted here") - } - } - fn get_content_sym (&'a self, value: &Value<'a>) -> Option>; - fn get_content_exp (&'a self, value: &Value<'a>) -> Option> { - try_delegate!(self, *value, When::>); - try_delegate!(self, *value, Either::, RenderBox<'a, E>>); - try_delegate!(self, *value, Align::>); - try_delegate!(self, *value, Bsp::, RenderBox<'a, E>>); - try_delegate!(self, *value, Fill::>); - try_delegate!(self, *value, Fixed::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Min::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Max::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Shrink::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Expand::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Push::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Pull::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Margin::<_, RenderBox<'a, E>>); - try_delegate!(self, *value, Padding::<_, RenderBox<'a, E>>); - None - } -} -#[macro_export] macro_rules! try_delegate { - ($s:ident, $atom:expr, $T:ty) => { - if let Some(value) = <$T>::try_from_atom($s, $atom) { - return Some(value.boxed()) - } - } -} -#[macro_export] macro_rules! try_from_expr { - (<$l:lifetime, $E:ident>: $Struct:ty: |$state:ident, $iter:ident|$body:expr) => { - impl<$l, $E: Output + $l, T: ViewContext<$l, $E>> TryFromAtom<$l, T> for $Struct { - fn try_from_expr ($state: &$l T, $iter: TokenIter<'a>) -> Option { - let mut $iter = $iter.clone(); - $body; - None - } - } - } -} diff --git a/plugin/Cargo.toml b/plugin/Cargo.toml index 6d571136..517a9cba 100644 --- a/plugin/Cargo.toml +++ b/plugin/Cargo.toml @@ -4,7 +4,8 @@ edition = "2021" version = "0.2.0" [dependencies] -tek_tui = { path = "../tui" } +tek_tui = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } + tek_jack = { path = "../jack" } tek_time = { path = "../time" } tek_midi = { path = "../midi" } diff --git a/sampler/Cargo.toml b/sampler/Cargo.toml index bc3532b4..1b0f8b77 100644 --- a/sampler/Cargo.toml +++ b/sampler/Cargo.toml @@ -4,7 +4,8 @@ edition = "2021" version = "0.2.0" [dependencies] -tek_tui = { path = "../tui" } +tek_tui = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } + tek_jack = { path = "../jack" } tek_time = { path = "../time" } tek_midi = { path = "../midi" } diff --git a/time/Cargo.toml b/time/Cargo.toml index 83d7f3f5..2891241b 100644 --- a/time/Cargo.toml +++ b/time/Cargo.toml @@ -4,9 +4,11 @@ edition = "2021" version = "0.2.0" [dependencies] +tek_input = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } +tek_edn = { git = "https://codeberg.org/unspeaker/tengri", ref = "5352a9d" } + tek_jack = { path = "../jack" } -tek_edn = { path = "../edn" } -tek_input = { path = "../input" } + atomic_float = "1.0.0" quanta = "0.12.3" #jack = { path = "../rust-jack" } diff --git a/tui/Cargo.toml b/tui/Cargo.toml deleted file mode 100644 index da5353c5..00000000 --- a/tui/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "tek_tui" -edition = "2021" -version = "0.2.0" - -[dependencies] -palette = { version = "0.7.6", features = [ "random" ] } -rand = "0.8.5" -crossterm = "0.28.1" -ratatui = { version = "0.29.0", features = [ "unstable-widget-ref", "underline-color" ] } -better-panic = "0.3.0" -konst = { version = "0.3.16", features = [ "rust_1_83" ] } - -tek_edn = { path = "../edn" } -tek_input = { path = "../input" } -tek_output = { path = "../output" } -tek_time = { path = "../time" } diff --git a/tui/README.md b/tui/README.md deleted file mode 100644 index 36606d52..00000000 --- a/tui/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# `tek_tui` - -the `Tui` struct (the *engine*) implements the -`tek_input::Input` and `tek_output::Output` traits. - -at launch, the `Tui` engine spawns two threads, -a **render thread** and an **input thread**. (the -application may spawn further threads, such as a -**jack thread**.) - -all threads communicate using shared ownership, -`Arc` and `Arc`. the engine and -application instances are expected to be wrapped -in `Arc`; internally, those synchronization -mechanisms may be used liberally. diff --git a/tui/examples/demo.rs.old b/tui/examples/demo.rs.old deleted file mode 100644 index a68d26d7..00000000 --- a/tui/examples/demo.rs.old +++ /dev/null @@ -1,144 +0,0 @@ -use tek::*; - -fn main () -> Usually<()> { - Tui::run(Arc::new(RwLock::new(Demo::new())))?; - Ok(()) -} - -pub struct Demo { - index: usize, - items: Vec>> -} - -impl Demo { - fn new () -> Self { - Self { - index: 0, - items: vec![ - //Box::new(tek_sequencer::TransportPlayPauseButton { - //_engine: Default::default(), - //transport: None, - //value: Some(TransportState::Stopped), - //focused: true - //}), - //Box::new(tek_sequencer::TransportPlayPauseButton { - //_engine: Default::default(), - //transport: None, - //value: Some(TransportState::Rolling), - //focused: false - //}), - ] - } - } -} - -impl Content for Demo { - type Engine = Tui; - fn content (&self) -> dyn Render { - let border_style = Style::default().fg(Color::Rgb(0,0,0)); - Align::Center(Layers::new(move|add|{ - - add(&Background(Color::Rgb(0,128,128)))?; - - add(&Margin::XY(1, 1, Stack::down(|add|{ - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(128,96,0)))?; - add(&Border(Square(border_style)))?; - add(&Margin::XY(2, 1, "..."))?; - Ok(()) - }).debug())?; - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(128,64,0)))?; - add(&Border(Lozenge(border_style)))?; - add(&Margin::XY(4, 2, "---"))?; - Ok(()) - }).debug())?; - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(96,64,0)))?; - add(&Border(SquareBold(border_style)))?; - add(&Margin::XY(6, 3, "~~~"))?; - Ok(()) - }).debug())?; - - Ok(()) - })).debug())?; - - Ok(()) - - })) - //Align::Center(Margin::X(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(128,0,0)))?; - //add(&Stack::down(|add|{ - //add(&Margin::Y(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(0,128,0)))?; - //add(&Align::Center("12345"))?; - //add(&Align::Center("FOO")) - //})))?; - //add(&Margin::XY(1, 1, Layers::new(|add|{ - //add(&Align::Center("1234567"))?; - //add(&Align::Center("BAR"))?; - //add(&Background(Color::Rgb(0,0,128))) - //}))) - //})) - //}))) - - //Align::Y(Layers::new(|add|{ - //add(&Background(Color::Rgb(128,0,0)))?; - //add(&Margin::X(1, Align::Center(Stack::down(|add|{ - //add(&Align::X(Margin::Y(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(0,128,0)))?; - //add(&Align::Center("12345"))?; - //add(&Align::Center("FOO")) - //})))?; - //add(&Margin::XY(1, 1, Layers::new(|add|{ - //add(&Align::Center("1234567"))?; - //add(&Align::Center("BAR"))?; - //add(&Background(Color::Rgb(0,0,128))) - //})))?; - //Ok(()) - //}))))) - //})) - } -} - -impl Handle for Demo { - fn handle (&mut self, from: &TuiIn) -> Perhaps { - use KeyCode::{PageUp, PageDown}; - match from.event() { - kexp!(PageUp) => { - self.index = (self.index + 1) % self.items.len(); - }, - kexp!(PageDown) => { - self.index = if self.index > 1 { - self.index - 1 - } else { - self.items.len() - 1 - }; - }, - _ => return Ok(None) - } - Ok(Some(true)) - } -} - -//lisp!(CONTENT Demo (LET - //(BORDER-STYLE (STYLE (FG (RGB 0 0 0)))) - //(BG-COLOR-0 (RGB 0 128 128)) - //(BG-COLOR-1 (RGB 128 96 0)) - //(BG-COLOR-2 (RGB 128 64 0)) - //(BG-COLOR-3 (RGB 96 64 0)) - //(CENTER (LAYERS - //(BACKGROUND BG-COLOR-0) - //(OUTSET-XY 1 1 (SPLIT-DOWN - //(LAYERS (BACKGROUND BG-COLOR-1) - //(BORDER SQUARE BORDER-STYLE) - //(OUTSET-XY 2 1 "...")) - //(LAYERS (BACKGROUND BG-COLOR-2) - //(BORDER LOZENGE BORDER-STYLE) - //(OUTSET-XY 4 2 "---")) - //(LAYERS (BACKGROUND BG-COLOR-3) - //(BORDER SQUARE-BOLD BORDER-STYLE) - //(OUTSET-XY 2 1 "~~~")))))))) diff --git a/tui/examples/edn01.edn b/tui/examples/edn01.edn deleted file mode 100644 index 7ff93d18..00000000 --- a/tui/examples/edn01.edn +++ /dev/null @@ -1 +0,0 @@ -:hello-world diff --git a/tui/examples/edn02.edn b/tui/examples/edn02.edn deleted file mode 100644 index 4f352a6d..00000000 --- a/tui/examples/edn02.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/s :hello :world) diff --git a/tui/examples/edn03.edn b/tui/examples/edn03.edn deleted file mode 100644 index 16222753..00000000 --- a/tui/examples/edn03.edn +++ /dev/null @@ -1 +0,0 @@ -(fill/xy :hello-world) diff --git a/tui/examples/edn04.edn b/tui/examples/edn04.edn deleted file mode 100644 index 9393669b..00000000 --- a/tui/examples/edn04.edn +++ /dev/null @@ -1 +0,0 @@ -(fixed/xy 20 10 :hello-world) diff --git a/tui/examples/edn05.edn b/tui/examples/edn05.edn deleted file mode 100644 index 90313ade..00000000 --- a/tui/examples/edn05.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/s (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn06.edn b/tui/examples/edn06.edn deleted file mode 100644 index e35abf0a..00000000 --- a/tui/examples/edn06.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/e (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn07.edn b/tui/examples/edn07.edn deleted file mode 100644 index 73703539..00000000 --- a/tui/examples/edn07.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/n (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn08.edn b/tui/examples/edn08.edn deleted file mode 100644 index afcde460..00000000 --- a/tui/examples/edn08.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/w (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn09.edn b/tui/examples/edn09.edn deleted file mode 100644 index 3ced7694..00000000 --- a/tui/examples/edn09.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/a (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn10.edn b/tui/examples/edn10.edn deleted file mode 100644 index 07af31e3..00000000 --- a/tui/examples/edn10.edn +++ /dev/null @@ -1 +0,0 @@ -(bsp/b (fixed/xy 5 6 :hello) (fixed/xy 7 8 :world)) diff --git a/tui/examples/edn11.edn b/tui/examples/edn11.edn deleted file mode 100644 index 1c47cb5f..00000000 --- a/tui/examples/edn11.edn +++ /dev/null @@ -1,11 +0,0 @@ -(bsp/s - (bsp/e (align/nw (fixed/xy 5 3 :hello)) - (bsp/e (align/n (fixed/xy 5 3 :hello)) - (align/ne (fixed/xy 5 3 :hello)))) - (bsp/s - (bsp/e (align/w (fixed/xy 5 3 :hello)) - (bsp/e (align/c (fixed/xy 5 3 :hello)) - (align/e (fixed/xy 5 3 :hello)))) - (bsp/e (align/sw (fixed/xy 5 3 :hello)) - (bsp/e (align/s (fixed/xy 5 3 :hello)) - (align/se (fixed/xy 5 3 :hello)))))) diff --git a/tui/examples/edn12.edn b/tui/examples/edn12.edn deleted file mode 100644 index 26e3f5f0..00000000 --- a/tui/examples/edn12.edn +++ /dev/null @@ -1,11 +0,0 @@ -(bsp/s - (bsp/e (fixed/xy 8 5 (align/nw :hello)) - (bsp/e (fixed/xy 8 5 (align/n :hello)) - (fixed/xy 8 5 (align/ne :hello)))) - (bsp/s - (bsp/e (fixed/xy 8 5 (align/w :hello)) - (bsp/e (fixed/xy 8 5 (align/c :hello)) - (fixed/xy 8 5 (align/e :hello)))) - (bsp/e (fixed/xy 8 5 (align/sw :hello)) - (bsp/e (fixed/xy 8 5 (align/s :hello)) - (fixed/xy 8 5 (align/se :hello)))))) diff --git a/tui/examples/edn13.edn b/tui/examples/edn13.edn deleted file mode 100644 index 8fe81c3a..00000000 --- a/tui/examples/edn13.edn +++ /dev/null @@ -1,11 +0,0 @@ -(bsp/s - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/nw :hello))) - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/n :hello))) - (grow/xy 1 1 (fixed/xy 8 5 (align/ne :hello))))) - (bsp/s - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/w :hello))) - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/c :hello))) - (grow/xy 1 1 (fixed/xy 8 5 (align/e :hello))))) - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/sw :hello))) - (bsp/e (grow/xy 1 1 (fixed/xy 8 5 (align/s :hello))) - (grow/xy 1 1 (fixed/xy 8 5 (align/se :hello))))))) diff --git a/tui/examples/edn99.edn b/tui/examples/edn99.edn deleted file mode 100644 index cac47263..00000000 --- a/tui/examples/edn99.edn +++ /dev/null @@ -1,73 +0,0 @@ -(align/c (bg/behind :bg0 (margin/xy 1 1 (col - (bg/behind :bg1 (border/around :border1 (margin/xy 2 1 :label1))) - (bg/behind :bg2 (border/around :border2 (margin/xy 4 2 :label2))) - (bg/behind :bg3 (border/around :border3 (margin/xy 6 3 :label3))))))) - - fn content (&self) -> dyn Render { - let border_style = Style::default().fg(Color::Rgb(0,0,0)); - Align::Center(Layers::new(move|add|{ - - add(&Background(Color::Rgb(0,128,128)))?; - - add(&Margin::XY(1, 1, Stack::down(|add|{ - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(128,96,0)))?; - add(&Border(Square(border_style)))?; - add(&Margin::XY(2, 1, "..."))?; - Ok(()) - }).debug())?; - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(128,64,0)))?; - add(&Border(Lozenge(border_style)))?; - add(&Margin::XY(4, 2, "---"))?; - Ok(()) - }).debug())?; - - add(&Layers::new(|add|{ - add(&Background(Color::Rgb(96,64,0)))?; - add(&Border(SquareBold(border_style)))?; - add(&Margin::XY(6, 3, "~~~"))?; - Ok(()) - }).debug())?; - - Ok(()) - })).debug())?; - - Ok(()) - - })) - //Align::Center(Margin::X(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(128,0,0)))?; - //add(&Stack::down(|add|{ - //add(&Margin::Y(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(0,128,0)))?; - //add(&Align::Center("12345"))?; - //add(&Align::Center("FOO")) - //})))?; - //add(&Margin::XY(1, 1, Layers::new(|add|{ - //add(&Align::Center("1234567"))?; - //add(&Align::Center("BAR"))?; - //add(&Background(Color::Rgb(0,0,128))) - //}))) - //})) - //}))) - - //Align::Y(Layers::new(|add|{ - //add(&Background(Color::Rgb(128,0,0)))?; - //add(&Margin::X(1, Align::Center(Stack::down(|add|{ - //add(&Align::X(Margin::Y(1, Layers::new(|add|{ - //add(&Background(Color::Rgb(0,128,0)))?; - //add(&Align::Center("12345"))?; - //add(&Align::Center("FOO")) - //})))?; - //add(&Margin::XY(1, 1, Layers::new(|add|{ - //add(&Align::Center("1234567"))?; - //add(&Align::Center("BAR"))?; - //add(&Background(Color::Rgb(0,0,128))) - //})))?; - //Ok(()) - //}))))) - //})) - } diff --git a/tui/examples/tui.rs b/tui/examples/tui.rs deleted file mode 100644 index 37fd116e..00000000 --- a/tui/examples/tui.rs +++ /dev/null @@ -1,66 +0,0 @@ -use tek_tui::{*, tek_input::*, tek_output::*}; -use tek_edn::*; -use std::sync::{Arc, RwLock}; -use crossterm::event::{*, KeyCode::*}; -use crate::ratatui::style::Color; -fn main () -> Usually<()> { - let state = Arc::new(RwLock::new(Example(10, Measure::new()))); - Tui::new().unwrap().run(&state)?; - Ok(()) -} -#[derive(Debug)] pub struct Example(usize, Measure); -const KEYMAP: &str = "(:left prev) (:right next)"; -handle!(TuiIn: |self: Example, input|{ - let keymap = SourceIter::new(KEYMAP); - let command = keymap.command::<_, ExampleCommand, _>(self, input); - if let Some(command) = command { - command.execute(self)?; - return Ok(Some(true)) - } - return Ok(None) -}); -enum ExampleCommand { Next, Previous } -atom_command!(ExampleCommand: |app: Example| { - (":prev" [] Some(Self::Previous)) - (":next" [] Some(Self::Next)) -}); -command!(|self: ExampleCommand, state: Example|match self { - Self::Next => - { state.0 = (state.0 + 1) % EXAMPLES.len(); None }, - Self::Previous => - { state.0 = if state.0 > 0 { state.0 - 1 } else { EXAMPLES.len() - 1 }; None }, -}); -const EXAMPLES: &'static [&'static str] = &[ - include_str!("edn01.edn"), - include_str!("edn02.edn"), - include_str!("edn03.edn"), - include_str!("edn04.edn"), - include_str!("edn05.edn"), - include_str!("edn06.edn"), - include_str!("edn07.edn"), - include_str!("edn08.edn"), - include_str!("edn09.edn"), - include_str!("edn10.edn"), - include_str!("edn11.edn"), - include_str!("edn12.edn"), - include_str!("edn13.edn"), -]; -view!(TuiOut: |self: Example|{ - let index = self.0 + 1; - let wh = self.1.wh(); - let src = EXAMPLES[self.0]; - let heading = format!("Example {}/{} in {:?}", index, EXAMPLES.len(), &wh); - let title = Tui::bg(Color::Rgb(60, 10, 10), Push::y(1, Align::n(heading))); - let code = Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", src)))); - let content = Tui::bg(Color::Rgb(10, 10, 60), View(self, SourceIter::new(src))); - self.1.of(Bsp::s(title, Bsp::n(""/*code*/, content))) -}; { - ":title" => Tui::bg(Color::Rgb(60, 10, 10), Push::y(1, Align::n(format!("Example {}/{}:", self.0 + 1, EXAMPLES.len())))).boxed(), - ":code" => Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", EXAMPLES[self.0])))).boxed(), - ":hello" => Tui::bg(Color::Rgb(10, 100, 10), "Hello").boxed(), - ":world" => Tui::bg(Color::Rgb(100, 10, 10), "world").boxed(), - ":hello-world" => "Hello world!".boxed() -}); -provide_bool!(bool: |self: Example| {}); -provide_num!(u16: |self: Example| {}); -provide_num!(usize: |self: Example| {}); diff --git a/tui/src/lib.rs b/tui/src/lib.rs deleted file mode 100644 index 8e49ddf6..00000000 --- a/tui/src/lib.rs +++ /dev/null @@ -1,57 +0,0 @@ -mod tui_buffer; pub use self::tui_buffer::*; -mod tui_color; pub use self::tui_color::*; -mod tui_content; pub use self::tui_content::*; -mod tui_engine; pub use self::tui_engine::*; -mod tui_file; pub use self::tui_file::*; -mod tui_input; pub use self::tui_input::*; -mod tui_output; pub use self::tui_output::*; -pub use ::tek_edn;// pub(crate) use ::tek_edn::*; -pub use ::tek_time; pub(crate) use ::tek_time::*; -pub use ::tek_input; pub(crate) use tek_input::*; -pub use ::tek_output; pub(crate) use tek_output::*; -pub use ::better_panic; pub(crate) use better_panic::{Settings, Verbosity}; -pub use ::palette; pub(crate) use ::palette::{*, convert::*, okhsl::*}; -pub use ::crossterm; pub(crate) use crossterm::{ - ExecutableCommand, - terminal::{EnterAlternateScreen, LeaveAlternateScreen, enable_raw_mode, disable_raw_mode}, - event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState}, -}; -pub use ::ratatui; pub(crate) use ratatui::{ - prelude::{Color, Style, Buffer}, - style::Modifier, - backend::{Backend, CrosstermBackend, ClearType}, - layout::{Size, Rect}, - buffer::Cell -}; -pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::*}}; -pub(crate) use std::io::{stdout, Stdout}; -pub(crate) use std::path::PathBuf; -pub(crate) use std::ffi::OsString; -#[macro_export] macro_rules! from { - ($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => { - impl $(<$($lt),+>)? From<$Source> for $Target { - fn from ($state:$Source) -> Self { $cb } - } - }; -} -#[cfg(test)] #[test] fn test_tui_engine () -> Usually<()> { - use crate::*; - use std::sync::{Arc, RwLock}; - struct TestComponent(String); - impl Content for TestComponent { - fn content (&self) -> impl Render { - Some(self.0.as_str()) - } - } - impl Handle for TestComponent { - fn handle (&mut self, from: &TuiIn) -> Perhaps { - Ok(None) - } - } - let engine = Tui::new()?; - engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed); - let state = TestComponent("hello world".into()); - let state = std::sync::Arc::new(std::sync::RwLock::new(state)); - //engine.run(&state)?; - Ok(()) -} diff --git a/tui/src/tui_buffer.rs b/tui/src/tui_buffer.rs deleted file mode 100644 index 465cc32f..00000000 --- a/tui/src/tui_buffer.rs +++ /dev/null @@ -1,39 +0,0 @@ -use crate::*; -pub fn buffer_update (buf: &mut Buffer, area: [u16;4], callback: &impl Fn(&mut Cell, u16, u16)) { - for row in 0..area.h() { - let y = area.y() + row; - for col in 0..area.w() { - let x = area.x() + col; - if x < buf.area.width && y < buf.area.height { - callback(buf.get_mut(x, y), col, row); - } - } - } -} -#[derive(Default)] pub struct BigBuffer { - pub width: usize, - pub height: usize, - pub content: Vec -} -impl std::fmt::Debug for BigBuffer { - fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - write!(f, "[BB {}x{} ({})]", self.width, self.height, self.content.len()) - } -} -impl BigBuffer { - pub fn new (width: usize, height: usize) -> Self { - Self { width, height, content: vec![Cell::default(); width*height] } - } - pub fn get (&self, x: usize, y: usize) -> Option<&Cell> { - let i = self.index_of(x, y); - self.content.get(i) - } - pub fn get_mut (&mut self, x: usize, y: usize) -> Option<&mut Cell> { - let i = self.index_of(x, y); - self.content.get_mut(i) - } - pub fn index_of (&self, x: usize, y: usize) -> usize { - y * self.width + x - } -} -from!(|size:(usize, usize)| BigBuffer = Self::new(size.0, size.1)); diff --git a/tui/src/tui_color.rs b/tui/src/tui_color.rs deleted file mode 100644 index cdf278e5..00000000 --- a/tui/src/tui_color.rs +++ /dev/null @@ -1,163 +0,0 @@ -use crate::*; -use rand::{thread_rng, distributions::uniform::UniformSampler}; -impl Tui { - pub const fn null () -> Color { Color::Reset } - pub const fn g (g: u8) -> Color { Color::Rgb(g, g, g) } - pub const fn red () -> Color { Color::Rgb(255,0, 0) } - pub const fn orange () -> Color { Color::Rgb(255,128,0) } - pub const fn yellow () -> Color { Color::Rgb(255,255,0) } - pub const fn brown () -> Color { Color::Rgb(128,255,0) } - pub const fn green () -> Color { Color::Rgb(0,255,0) } - pub const fn electric () -> Color { Color::Rgb(0,255,128) } - //fn bg0 () -> Color { Color::Rgb(20, 20, 20) } - //fn bg () -> Color { Color::Rgb(28, 35, 25) } - //fn border_bg () -> Color { Color::Rgb(40, 50, 30) } - //fn border_fg (f: bool) -> Color { if f { Self::bo1() } else { Self::bo2() } } - //fn title_fg (f: bool) -> Color { if f { Self::ti1() } else { Self::ti2() } } - //fn separator_fg (_: bool) -> Color { Color::Rgb(0, 0, 0) } - //fn mode_bg () -> Color { Color::Rgb(150, 160, 90) } - //fn mode_fg () -> Color { Color::Rgb(255, 255, 255) } - //fn status_bar_bg () -> Color { Color::Rgb(28, 35, 25) } - //fn bo1 () -> Color { Color::Rgb(100, 110, 40) } - //fn bo2 () -> Color { Color::Rgb(70, 80, 50) } - //fn ti1 () -> Color { Color::Rgb(150, 160, 90) } - //fn ti2 () -> Color { Color::Rgb(120, 130, 100) } -} -pub trait HasColor { fn color (&self) -> ItemColor; } -#[macro_export] macro_rules! has_color { - (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? HasColor for $Struct $(<$($L),*$($T),*>)? { - fn color (&$self) -> ItemColor { $cb } - } - } -} -/// A color in OKHSL and RGB representations. -#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemColor { - pub okhsl: Okhsl, - pub rgb: Color, -} -from!(|okhsl: Okhsl|ItemColor = Self { okhsl, rgb: okhsl_to_rgb(okhsl) }); -pub fn okhsl_to_rgb (color: Okhsl) -> Color { - let Srgb { red, green, blue, .. }: Srgb = Srgb::from_color_unclamped(color); - Color::Rgb((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8,) -} -from!(|rgb: Color|ItemColor = Self { rgb, okhsl: rgb_to_okhsl(rgb) }); -pub fn rgb_to_okhsl (color: Color) -> Okhsl { - if let Color::Rgb(r, g, b) = color { - Okhsl::from_color(Srgb::new(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0)) - } else { - unreachable!("only Color::Rgb is supported") - } -} -// A single color within item theme parameters, in OKHSL and RGB representations. -impl ItemColor { - pub const fn from_rgb (rgb: Color) -> Self { - Self { rgb, okhsl: Okhsl::new_const(OklabHue::new(0.0), 0.0, 0.0) } - } - pub const fn from_okhsl (okhsl: Okhsl) -> Self { - Self { rgb: Color::Rgb(0, 0, 0), okhsl } - } - pub fn random () -> Self { - let mut rng = thread_rng(); - let lo = Okhsl::new(-180.0, 0.01, 0.25); - let hi = Okhsl::new( 180.0, 0.9, 0.5); - UniformOkhsl::new(lo, hi).sample(&mut rng).into() - } - pub fn random_dark () -> Self { - let mut rng = thread_rng(); - let lo = Okhsl::new(-180.0, 0.025, 0.075); - let hi = Okhsl::new( 180.0, 0.5, 0.150); - UniformOkhsl::new(lo, hi).sample(&mut rng).into() - } - pub fn random_near (color: Self, distance: f32) -> Self { - color.mix(Self::random(), distance) - } - pub fn mix (&self, other: Self, distance: f32) -> Self { - if distance > 1.0 { panic!("color mixing takes distance between 0.0 and 1.0"); } - self.okhsl.mix(other.okhsl, distance).into() - } -} -/// A color in OKHSL and RGB with lighter and darker variants. -#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct ItemPalette { - pub base: ItemColor, - pub light: ItemColor, - pub lighter: ItemColor, - pub lightest: ItemColor, - pub dark: ItemColor, - pub darker: ItemColor, - pub darkest: ItemColor, -} -impl ItemPalette { - pub const G: [Self;256] = { - let mut builder = konst::array::ArrayBuilder::new(); - while !builder.is_full() { - let index = builder.len() as u8; - let light = (index as f64 * 1.3) as u8; - let lighter = (index as f64 * 1.6) as u8; - let lightest = (index as f64 * 1.9) as u8; - let dark = (index as f64 * 0.9) as u8; - let darker = (index as f64 * 0.6) as u8; - let darkest = (index as f64 * 0.3) as u8; - builder.push(ItemPalette { - base: ItemColor::from_rgb(Color::Rgb(index, index, index )), - light: ItemColor::from_rgb(Color::Rgb(light, light, light, )), - lighter: ItemColor::from_rgb(Color::Rgb(lighter, lighter, lighter, )), - lightest: ItemColor::from_rgb(Color::Rgb(lightest, lightest, lightest, )), - dark: ItemColor::from_rgb(Color::Rgb(dark, dark, dark, )), - darker: ItemColor::from_rgb(Color::Rgb(darker, darker, darker, )), - darkest: ItemColor::from_rgb(Color::Rgb(darkest, darkest, darkest, )), - }); - } - builder.build() - }; - pub fn random () -> Self { ItemColor::random().into() } - pub fn random_near (color: Self, distance: f32) -> Self { - color.base.mix(ItemColor::random(), distance).into() - } - pub const G00: Self = { - let color: ItemColor = ItemColor { - okhsl: Okhsl { hue: OklabHue::new(0.0), lightness: 0.0, saturation: 0.0 }, - rgb: Color::Rgb(0, 0, 0) - }; - Self { - base: color, - light: color, - lighter: color, - lightest: color, - dark: color, - darker: color, - darkest: color, - } - }; - pub fn from_tui_color (base: Color) -> Self { - Self::from_item_color(ItemColor::from_rgb(base)) - } - pub fn from_item_color (base: ItemColor) -> Self { - let mut light = base.okhsl; - light.lightness = (light.lightness * 1.3).min(1.0); - let mut lighter = light; - lighter.lightness = (lighter.lightness * 1.3).min(1.0); - let mut lightest = base.okhsl; - lightest.lightness = 0.95; - let mut dark = base.okhsl; - dark.lightness = (dark.lightness * 0.75).max(0.0); - dark.saturation = (dark.saturation * 0.75).max(0.0); - let mut darker = dark; - darker.lightness = (darker.lightness * 0.66).max(0.0); - darker.saturation = (darker.saturation * 0.66).max(0.0); - let mut darkest = darker; - darkest.lightness = 0.1; - darkest.saturation = (darkest.saturation * 0.50).max(0.0); - Self { - base, - light: light.into(), - lighter: lighter.into(), - lightest: lightest.into(), - dark: dark.into(), - darker: darker.into(), - darkest: darkest.into(), - } - } -} -from!(|base: Color| ItemPalette = Self::from_tui_color(base)); -from!(|base: ItemColor|ItemPalette = Self::from_item_color(base)); diff --git a/tui/src/tui_content.rs b/tui/src/tui_content.rs deleted file mode 100644 index 5db1daca..00000000 --- a/tui/src/tui_content.rs +++ /dev/null @@ -1,522 +0,0 @@ -use crate::*; -use crate::Color::*; -use ratatui::prelude::Position; -macro_rules! impl_content_layout_render { - ($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => { - impl Content<$Output> for $Struct { - fn layout (&$self, $to: [u16;4]) -> [u16;4] { $layout } - fn render (&$self, $to: &mut $Output) { $render } - } - } -} -impl_content_layout_render!(TuiOut: |self: &str, to| - layout = to.center_xy([self.chars().count() as u16, 1]); - render = {let [x, y, ..] = Content::layout(self, to.area()); - to.blit(self, x, y, None)}); -impl_content_layout_render!(TuiOut: |self: String, to| - layout = to.center_xy([self.chars().count() as u16, 1]); - render = {let [x, y, ..] = Content::layout(self, to.area()); - to.blit(self, x, y, None)}); -impl_content_layout_render!(TuiOut: |self: std::sync::RwLock, to| - layout = Content::::layout(&self.read().unwrap(), to); - render = Content::::render(&self.read().unwrap(), to)); -impl_content_layout_render!(TuiOut: |self: std::sync::RwLockReadGuard<'_, String>, to| - layout = Content::::layout(&**self, to); - render = Content::::render(&**self, to)); -impl_content_layout_render!(TuiOut: |self: Arc, to| - layout = to.center_xy([self.chars().count() as u16, 1]); - render = to.blit(self, to.area.x(), to.area.y(), None)); -impl> Content for std::sync::Arc { - fn layout (&self, to: [u16;4]) -> [u16;4] { - Content::::layout(&**self, to) - } - fn render (&self, to: &mut TuiOut) { - Content::::render(&**self, to) - } -} - -pub struct FieldH(pub ItemPalette, pub T, pub U); -impl, U: Content> Content for FieldH { - fn content (&self) -> impl Render { - let Self(ItemPalette { darkest, dark, lighter, lightest, .. }, title, value) = self; - row!( - Tui::fg_bg(dark.rgb, darkest.rgb, "▐"), - Tui::fg_bg(lighter.rgb, dark.rgb, Tui::bold(true, title)), - Tui::fg_bg(dark.rgb, darkest.rgb, "▌"), - Tui::fg_bg(lightest.rgb, darkest.rgb, value), - ) - } -} - -pub struct FieldV(pub ItemPalette, pub T, pub U); -impl, U: Content> Content for FieldV { - fn content (&self) -> impl Render { - let Self(ItemPalette { darkest, dark, lighter, lightest, .. }, title, value) = self; - let sep1 = Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▐")); - let sep2 = Tui::bg(darkest.rgb, Tui::fg(dark.rgb, "▌")); - let title = Tui::bg(dark.rgb, Tui::fg(lighter.rgb, Tui::bold(true, title))); - let value = Tui::bg(darkest.rgb, Tui::fg(lightest.rgb, value)); - Bsp::e(Bsp::s(row!(sep1, title, sep2), value), " ") - } -} - -pub struct Repeat<'a>(pub &'a str); -impl Content for Repeat<'_> { - fn layout (&self, to: [u16;4]) -> [u16;4] { to } - fn render (&self, to: &mut TuiOut) { - let [x, y, w, h] = to.area().xywh(); - let a = self.0.len(); - for (_v, y) in (y..y+h).enumerate() { - for (u, x) in (x..x+w).enumerate() { - if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) { - let u = u % a; - cell.set_symbol(&self.0[u..u+1]); - } - } - } - } -} - -pub struct RepeatV<'a>(pub &'a str); -impl Content for RepeatV<'_> { - fn layout (&self, to: [u16;4]) -> [u16;4] { to } - fn render (&self, to: &mut TuiOut) { - let [x, y, _w, h] = to.area().xywh(); - for y in y..y+h { - if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) { - cell.set_symbol(&self.0); - } - } - } -} - -pub struct RepeatH<'a>(pub &'a str); -impl Content for RepeatH<'_> { - fn layout (&self, to: [u16;4]) -> [u16;4] { to } - fn render (&self, to: &mut TuiOut) { - let [x, y, w, _h] = to.area().xywh(); - for x in x..x+w { - if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) { - cell.set_symbol(&self.0); - } - } - } -} - -pub struct ScrollbarV { - pub offset: usize, - pub length: usize, - pub total: usize, -} -impl ScrollbarV { - const ICON_DEC: &[char] = &['▲']; - const ICON_INC: &[char] = &['▼']; -} -impl Content for ScrollbarV { - fn render (&self, to: &mut TuiOut) { - let [x, y1, _w, h] = to.area().xywh(); - let y2 = y1 + h; - for (i, y) in (y1..=y2).enumerate() { - if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) { - if (i as usize) < (Self::ICON_DEC.len()) { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Rgb(0, 0, 0)); - cell.set_char(Self::ICON_DEC[i as usize]); - } else if (i as usize) > (h as usize - Self::ICON_INC.len()) { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Rgb(0, 0, 0)); - cell.set_char(Self::ICON_INC[h as usize - i]); - } else if false { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Reset); - cell.set_char('‖'); // ━ - } else { - cell.set_fg(Rgb(0, 0, 0)); - cell.set_bg(Reset); - cell.set_char('╎'); // ━ - } - } - } - } -} - -pub struct ScrollbarH { - pub offset: usize, - pub length: usize, - pub total: usize, -} -impl ScrollbarH { - const ICON_DEC: &[char] = &[' ', '🞀', ' ']; - const ICON_INC: &[char] = &[' ', '🞂', ' ']; -} -impl Content for ScrollbarH { - fn render (&self, to: &mut TuiOut) { - let [x1, y, w, _h] = to.area().xywh(); - let x2 = x1 + w; - for (i, x) in (x1..=x2).enumerate() { - if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) { - if i < (Self::ICON_DEC.len()) { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Rgb(0, 0, 0)); - cell.set_char(Self::ICON_DEC[x as usize]); - } else if i > (w as usize - Self::ICON_INC.len()) { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Rgb(0, 0, 0)); - cell.set_char(Self::ICON_INC[w as usize - i]); - } else if false { - cell.set_fg(Rgb(255, 255, 255)); - cell.set_bg(Reset); - cell.set_char('━'); - } else { - cell.set_fg(Rgb(0, 0, 0)); - cell.set_bg(Reset); - cell.set_char('╌'); - } - } - } - } -} - -/// A cell that takes up 3 rows on its own, -/// but stacks, giving (N+1)*2 rows per N cells. -pub struct Phat { - pub width: u16, - pub height: u16, - pub content: T, - pub colors: [Color;4], -} -impl Phat { - /// A phat line - pub fn lo (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▄"))) - } - /// A phat line - pub fn hi (fg: Color, bg: Color) -> impl Content { - Fixed::y(1, Tui::fg_bg(fg, bg, RepeatH(&"▀"))) - } -} -impl> Content for Phat { - fn content (&self) -> impl Render { - let [fg, bg, hi, lo] = self.colors; - let top = Fixed::y(1, Self::lo(bg, hi)); - let low = Fixed::y(1, Self::hi(bg, lo)); - let content = Tui::fg_bg(fg, bg, &self.content); - Min::xy(self.width, self.height, Bsp::s(top, Bsp::n(low, Fill::xy(content)))) - } -} - -pub trait TuiStyle { - fn fg > (color: Color, w: R) -> Foreground { - Foreground(color, w) - } - fn bg > (color: Color, w: R) -> Background { - Background(color, w) - } - fn fg_bg > (fg: Color, bg: Color, w: R) -> Background> { - Background(bg, Foreground(fg, w)) - } - fn bold > (enable: bool, w: R) -> Bold { - Bold(enable, w) - } - fn border , S: BorderStyle> (enable: bool, style: S, w: R) -> Bordered { - Bordered(enable, style, w) - } -} - -impl TuiStyle for Tui {} - -pub struct Bold>(pub bool, R); -impl> Content for Bold { - fn content (&self) -> impl Render { &self.1 } - fn render (&self, to: &mut TuiOut) { - to.fill_bold(to.area(), self.0); - self.1.render(to) - } -} - -pub struct Foreground>(pub Color, R); -impl> Content for Foreground { - fn content (&self) -> impl Render { &self.1 } - fn render (&self, to: &mut TuiOut) { - to.fill_fg(to.area(), self.0); - self.1.render(to) - } -} - -pub struct Background>(pub Color, R); -impl> Content for Background { - fn content (&self) -> impl Render { &self.1 } - fn render (&self, to: &mut TuiOut) { - to.fill_bg(to.area(), self.0); - self.1.render(to) - } -} - -pub struct Styled>(pub Option