diff --git a/.config/config.toml b/.config/config.toml index 522dae5..1ad8fea 100644 --- a/.config/config.toml +++ b/.config/config.toml @@ -12,7 +12,7 @@ enter = "SelectEntry" ctrl-enter = "SendToChannel" ctrl-s = "ToggleChannelSelection" -[keybindings.ChannelSelection] +[keybindings.Guide] esc = "Quit" down = "SelectNextEntry" up = "SelectPrevEntry" diff --git a/Cargo.lock b/Cargo.lock index ad917ae..64c7318 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -67,43 +67,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "arc-swap" @@ -111,6 +111,12 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + [[package]] name = "async-trait" version = "0.1.83" @@ -119,7 +125,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -217,9 +223,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "camino" @@ -270,9 +276,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.30" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "shlex", ] @@ -328,7 +334,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -372,9 +378,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compact_str" @@ -393,14 +399,13 @@ dependencies = [ [[package]] name = "config" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" dependencies = [ "async-trait", "convert_case", "json5", - "lazy_static", "nom", "pathdiff", "ron", @@ -408,7 +413,7 @@ dependencies = [ "serde", "serde_json", "toml", - "yaml-rust", + "yaml-rust2", ] [[package]] @@ -559,7 +564,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -570,7 +575,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -600,7 +605,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -610,7 +615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -697,6 +702,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -845,7 +859,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -962,18 +976,18 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" +checksum = "10f78312288bd02052be5dbc2ecbc342c9f4eb791986d86c0a5c06b92dc72efa" dependencies = [ "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" +checksum = "6c28b58ba04f0c004722344390af9dbc85888fbb84be1981afb934da4114d4cf" dependencies = [ "thiserror", ] @@ -1015,9 +1029,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c" +checksum = "f3de3fdca9c75fa4b83a76583d265fa49b1de6b088ebcd210749c24ceeb74660" dependencies = [ "bitflags 2.6.0", "bstr", @@ -1028,9 +1042,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c84b7af01e68daf7a6bb8bb909c1ff5edb3ce4326f1f43063a5a96d3c3c8a5" +checksum = "d10d543ac13c97292a15e8e8b7889cd006faf739777437ed95362504b8fe81a0" dependencies = [ "bstr", "itoa", @@ -1227,9 +1241,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.11" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" +checksum = "c04e5a94fdb56b1e91eb7df2658ad16832428b8eeda24ff1a0f0288de2bce554" dependencies = [ "bstr", "gix-trace", @@ -1240,9 +1254,9 @@ dependencies = [ [[package]] name = "gix-quote" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" +checksum = "f89f9a1525dcfd9639e282ea939f5ab0d09d93cf2b90c1fc6104f1b9582a8e49" dependencies = [ "bstr", "gix-utils", @@ -1317,9 +1331,9 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f" +checksum = "a2007538eda296445c07949cf04f4a767307d887184d6b3e83e2d636533ddc6e" dependencies = [ "bitflags 2.6.0", "gix-path", @@ -1344,9 +1358,9 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" +checksum = "04bdde120c29f1fc23a24d3e115aeeea3d60d8e65bab92cc5f9d90d9302eb952" [[package]] name = "gix-traverse" @@ -1381,9 +1395,9 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" +checksum = "ba427e3e9599508ed98a6ddf8ed05493db114564e338e41f6a996d2e4790335f" dependencies = [ "fastrand", "unicode-normalization", @@ -1391,9 +1405,9 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86" +checksum = "e187b263461bc36cea17650141567753bc6207d036cedd1de6e81a52f277ff68" dependencies = [ "bstr", "thiserror", @@ -1412,12 +1426,6 @@ dependencies = [ "regex-syntax 0.8.5", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" - [[package]] name = "hashbrown" version = "0.14.5" @@ -1439,6 +1447,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "heck" version = "0.5.0" @@ -1540,7 +1557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1608,9 +1625,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libredox" @@ -1822,12 +1839,12 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-multimap" -version = "0.6.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ "dlv-list", - "hashbrown 0.13.2", + "hashbrown 0.14.5", ] [[package]] @@ -1925,7 +1942,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -1941,9 +1958,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1988,9 +2005,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -2083,9 +2100,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -2139,9 +2156,9 @@ dependencies = [ [[package]] name = "rust-ini" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" dependencies = [ "cfg-if", "ordered-multimap", @@ -2213,29 +2230,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -2379,7 +2396,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2395,9 +2412,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -2475,7 +2492,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2509,22 +2526,22 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2596,9 +2613,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", @@ -2620,7 +2637,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2676,7 +2693,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] [[package]] @@ -2743,12 +2760,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -2825,9 +2839,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", ] @@ -3119,6 +3133,17 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "yaml-rust2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + [[package]] name = "yansi" version = "1.0.1" @@ -3142,5 +3167,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.85", ] diff --git a/crates/television/app.rs b/crates/television/app.rs index 88f58be..172ffe9 100644 --- a/crates/television/app.rs +++ b/crates/television/app.rs @@ -52,12 +52,11 @@ */ use std::sync::Arc; - use color_eyre::Result; use tokio::sync::{mpsc, Mutex}; use tracing::{debug, info}; -use crate::channels::{TelevisionChannel, CliTvChannel}; +use crate::channels::{CliTvChannel, TelevisionChannel}; use crate::television::Television; use crate::{ action::Action, diff --git a/crates/television/channels.rs b/crates/television/channels.rs index 671965d..e647bdf 100644 --- a/crates/television/channels.rs +++ b/crates/television/channels.rs @@ -3,12 +3,12 @@ use color_eyre::eyre::Result; use television_derive::{Broadcast, CliChannel, UnitChannel}; mod alias; -pub mod channels; mod env; mod files; mod git_repos; pub mod stdin; mod text; +pub mod tv_guide; /// The interface that all television channels must implement. /// @@ -78,11 +78,11 @@ pub trait OnAir: Send { /// The available television channels. /// /// Each channel is represented by a variant of the enum and should implement -/// the `TelevisionChannel` trait. +/// the `OnAir` trait. /// /// # Important /// When adding a new channel, make sure to add a new variant to this enum and -/// implement the `TelevisionChannel` trait for it. +/// implement the `OnAir` trait for it. /// /// # Derive /// The `CliChannel` derive macro generates the necessary glue code to @@ -100,7 +100,7 @@ pub enum TelevisionChannel { Text(text::Channel), Stdin(stdin::Channel), Alias(alias::Channel), - Channel(channels::SelectionChannel), + TvGuide(tv_guide::TvGuide), } /// NOTE: this could be generated by a derive macro diff --git a/crates/television/channels/alias.rs b/crates/television/channels/alias.rs index cb39def..da407d6 100644 --- a/crates/television/channels/alias.rs +++ b/crates/television/channels/alias.rs @@ -68,6 +68,7 @@ fn get_raw_aliases(shell: &str) -> Vec { .map(std::string::ToString::to_string) .collect() } + // TODO: add more shells _ => Vec::new(), } } @@ -132,7 +133,7 @@ impl OnAir for Channel { .matched_items( offset ..(num_entries + offset) - .min(snapshot.matched_item_count()), + .min(snapshot.matched_item_count()), ) .map(move |item| { snapshot.pattern().column_pattern(0).indices( @@ -209,7 +210,7 @@ async fn load_aliases(injector: Injector) { debug!("Current shell: {}", shell); let raw_aliases = get_raw_aliases(shell); - let parsed_aliases = raw_aliases + raw_aliases .iter() .filter_map(|alias| { let mut parts = alias.split('='); @@ -223,11 +224,9 @@ async fn load_aliases(injector: Injector) { } None }) - .collect::>(); - - for alias in parsed_aliases { - let _ = injector.push(alias.clone(), |_, cols| { - cols[0] = (alias.name.clone() + &alias.value).into(); + .for_each(|alias| { + let _ = injector.push(alias.clone(), |_, cols| { + cols[0] = (alias.name.clone() + &alias.value).into(); + }); }); - } } diff --git a/crates/television/channels/files.rs b/crates/television/channels/files.rs index 27f1a29..af86e1e 100644 --- a/crates/television/channels/files.rs +++ b/crates/television/channels/files.rs @@ -3,15 +3,11 @@ use nucleo::{ pattern::{CaseMatching, Normalization}, Config, Injector, Nucleo, }; -use std::{ - os::unix::ffi::OsStrExt, - path::{Path, PathBuf}, - sync::Arc, -}; +use std::{os::unix::ffi::OsStrExt, path::PathBuf, sync::Arc}; use ignore::DirEntry; -use super::OnAir; +use super::{OnAir, TelevisionChannel}; use crate::previewers::PreviewType; use crate::utils::files::{walk_builder, DEFAULT_NUM_THREADS}; use crate::{ @@ -31,7 +27,7 @@ pub struct Channel { } impl Channel { - pub fn new(starting_dir: &Path) -> Self { + pub fn new(paths: Vec) -> Self { let matcher = Nucleo::new( Config::DEFAULT.match_paths(), Arc::new(|| {}), @@ -39,10 +35,7 @@ impl Channel { 1, ); // start loading files in the background - let crawl_handle = tokio::spawn(load_files( - starting_dir.to_path_buf(), - matcher.injector(), - )); + let crawl_handle = tokio::spawn(load_files(paths, matcher.injector())); Channel { matcher, last_pattern: String::new(), @@ -58,7 +51,24 @@ impl Channel { impl Default for Channel { fn default() -> Self { - Self::new(&std::env::current_dir().unwrap()) + Self::new(vec![std::env::current_dir().unwrap()]) + } +} + +impl From for Channel { + fn from(channel: TelevisionChannel) -> Self { + match channel { + TelevisionChannel::Files(channel) => channel, + TelevisionChannel::GitRepos(mut channel) => { + let git_project_paths = channel + .results(channel.result_count(), 0) + .iter() + .map(|entry| PathBuf::from(entry.name.clone())) + .collect(); + Self::new(git_project_paths) + } + _ => Channel::default(), + } } } @@ -76,14 +86,6 @@ impl OnAir for Channel { } } - fn result_count(&self) -> u32 { - self.result_count - } - - fn total_count(&self) -> u32 { - self.total_count - } - fn results(&mut self, num_entries: u32, offset: u32) -> Vec { let status = self.matcher.tick(Self::MATCHER_TICK_TIMEOUT); let snapshot = self.matcher.snapshot(); @@ -99,7 +101,7 @@ impl OnAir for Channel { .matched_items( offset ..(num_entries + offset) - .min(snapshot.matched_item_count()), + .min(snapshot.matched_item_count()), ) .map(move |item| { snapshot.pattern().column_pattern(0).indices( @@ -130,6 +132,14 @@ impl OnAir for Channel { }) } + fn result_count(&self) -> u32 { + self.result_count + } + + fn total_count(&self) -> u32 { + self.total_count + } + fn running(&self) -> bool { self.running } @@ -140,10 +150,17 @@ impl OnAir for Channel { } #[allow(clippy::unused_async)] -async fn load_files(path: PathBuf, injector: Injector) { +async fn load_files(paths: Vec, injector: Injector) { + if paths.is_empty() { + return; + } let current_dir = std::env::current_dir().unwrap(); - let walker = - walk_builder(&path, *DEFAULT_NUM_THREADS, None).build_parallel(); + let mut builder = + walk_builder(&paths[0], *DEFAULT_NUM_THREADS, None, None); + paths[1..].iter().for_each(|path| { + builder.add(path); + }); + let walker = builder.build_parallel(); walker.run(|| { let injector = injector.clone(); diff --git a/crates/television/channels/git_repos.rs b/crates/television/channels/git_repos.rs index de59ee6..c00186c 100644 --- a/crates/television/channels/git_repos.rs +++ b/crates/television/channels/git_repos.rs @@ -6,7 +6,7 @@ use nucleo::{ Config, Nucleo, }; use parking_lot::Mutex; -use std::{collections::HashSet, sync::Arc}; +use std::{collections::HashSet, path::PathBuf, sync::Arc}; use tokio::{ sync::{oneshot, watch}, task::JoinHandle, @@ -154,6 +154,51 @@ impl OnAir for Channel { } } +fn get_ignored_paths() -> Vec { + let mut ignored_paths = Vec::new(); + + if let Some(home) = std::env::home_dir() { + #[cfg(target_os = "macos")] + { + ignored_paths.push(home.join("Library")); + ignored_paths.push(home.join("Applications")); + ignored_paths.push(home.join("Music")); + ignored_paths.push(home.join("Pictures")); + ignored_paths.push(home.join("Movies")); + ignored_paths.push(home.join("Downloads")); + ignored_paths.push(home.join("Public")); + } + + #[cfg(target_os = "linux")] + { + ignored_paths.push(home.join(".cache")); + ignored_paths.push(home.join(".config")); + ignored_paths.push(home.join(".local")); + ignored_paths.push(home.join(".thumbnails")); + ignored_paths.push(home.join("Downloads")); + ignored_paths.push(home.join("Public")); + ignored_paths.push(home.join("snap")); + ignored_paths.push(home.join(".snap")); + } + + #[cfg(target_os = "windows")] + { + ignored_paths.push(home.join("AppData")); + ignored_paths.push(home.join("Downloads")); + ignored_paths.push(home.join("Documents")); + ignored_paths.push(home.join("Music")); + ignored_paths.push(home.join("Pictures")); + ignored_paths.push(home.join("Videos")); + } + + // Common paths to ignore for all platforms + ignored_paths.push(home.join("node_modules")); + ignored_paths.push(home.join("venv")); + ignored_paths.push(PathBuf::from("/tmp")); + } + + ignored_paths +} #[allow(clippy::unused_async)] async fn crawl_for_repos( starting_point: std::path::PathBuf, @@ -167,6 +212,7 @@ async fn crawl_for_repos( &starting_point, *DEFAULT_NUM_THREADS, Some(walker_overrides_builder.build().unwrap()), + Some(get_ignored_paths()), ) .build_parallel(); diff --git a/crates/television/channels/text.rs b/crates/television/channels/text.rs index 1c1ee88..d03ce85 100644 --- a/crates/television/channels/text.rs +++ b/crates/television/channels/text.rs @@ -172,13 +172,25 @@ impl OnAir for Channel { /// a lot of files (e.g. starting tv in $HOME). const MAX_FILE_SIZE: u64 = 4 * 1024 * 1024; +/// The maximum number of lines we're willing to keep in memory. +/// +/// TODO: this should be configurable by the user depending on the amount of +/// memory they have/are willing to use. +/// +/// This is to prevent taking humongous amounts of memory when searching in +/// a lot of files (e.g. starting tv in $HOME). +/// +/// This is a soft limit, we might go over it a bit. +/// +/// A typical line should take somewhere around 100 bytes in memory (for utf8 english text), +/// so this should take around 100 x `5_000_000` = 500MB of memory. const MAX_IN_MEMORY_LINES: usize = 5_000_000; #[allow(clippy::unused_async)] async fn load_candidates(path: PathBuf, injector: Injector) { let current_dir = std::env::current_dir().unwrap(); let walker = - walk_builder(&path, *DEFAULT_NUM_THREADS, None).build_parallel(); + walk_builder(&path, *DEFAULT_NUM_THREADS, None, None).build_parallel(); let lines_in_mem = Arc::new(AtomicUsize::new(0)); diff --git a/crates/television/channels/channels.rs b/crates/television/channels/tv_guide.rs similarity index 95% rename from crates/television/channels/channels.rs rename to crates/television/channels/tv_guide.rs index 2639a67..19dc125 100644 --- a/crates/television/channels/channels.rs +++ b/crates/television/channels/tv_guide.rs @@ -14,7 +14,7 @@ use crate::{ previewers::PreviewType, }; -pub struct SelectionChannel { +pub struct TvGuide { matcher: Nucleo, last_pattern: String, result_count: u32, @@ -24,7 +24,7 @@ pub struct SelectionChannel { const NUM_THREADS: usize = 1; -impl SelectionChannel { +impl TvGuide { pub fn new() -> Self { let matcher = Nucleo::new( Config::DEFAULT, @@ -38,7 +38,7 @@ impl SelectionChannel { cols[0] = (*e).to_string().into(); }); } - SelectionChannel { + TvGuide { matcher, last_pattern: String::new(), result_count: 0, @@ -50,7 +50,7 @@ impl SelectionChannel { const MATCHER_TICK_TIMEOUT: u64 = 2; } -impl Default for SelectionChannel { +impl Default for TvGuide { fn default() -> Self { Self::new() } @@ -61,7 +61,7 @@ const TV_ICON: FileIcon = FileIcon { color: "#ffffff", }; -impl OnAir for SelectionChannel { +impl OnAir for TvGuide { fn find(&mut self, pattern: &str) { if pattern != self.last_pattern { self.matcher.pattern.reparse( diff --git a/crates/television/previewers/directory.rs b/crates/television/previewers/directory.rs index c283426..95216b0 100644 --- a/crates/television/previewers/directory.rs +++ b/crates/television/previewers/directory.rs @@ -80,7 +80,9 @@ fn tree>( p.as_ref(), p.as_ref().parent().unwrap().to_str().unwrap(), )); - let w = walk_builder(p.as_ref(), 1, None).max_depth(Some(1)).build(); + let w = walk_builder(p.as_ref(), 1, None, None) + .max_depth(Some(1)) + .build(); let mut level_entry_count: u8 = 0; for path in w.skip(1).filter_map(std::result::Result::ok) { diff --git a/crates/television/television.rs b/crates/television/television.rs index 451e88a..f84d327 100644 --- a/crates/television/television.rs +++ b/crates/television/television.rs @@ -22,14 +22,11 @@ use crate::ui::preview::DEFAULT_PREVIEW_TITLE_FG; use crate::ui::results::build_results_list; use crate::utils::strings::EMPTY_STRING; use crate::{action::Action, config::Config}; -use crate::{channels::channels::SelectionChannel, ui::get_border_style}; +use crate::{channels::tv_guide::TvGuide, ui::get_border_style}; +use crate::{channels::OnAir, utils::strings::shrink_with_ellipsis}; use crate::{ channels::TelevisionChannel, ui::input::actions::InputActionHandler, }; -use crate::{ - channels::{OnAir, UnitChannel}, - utils::strings::shrink_with_ellipsis, -}; use crate::{ entry::{Entry, ENTRY_PLACEHOLDER}, ui::spinner::Spinner, @@ -39,7 +36,7 @@ use crate::{previewers::Previewer, ui::spinner::SpinnerState}; #[derive(PartialEq, Copy, Clone, Hash, Eq, Debug, Serialize, Deserialize)] pub enum Mode { Channel, - ChannelSelection, + Guide, SendToChannel, } @@ -47,8 +44,7 @@ pub struct Television { action_tx: Option>, pub config: Config, channel: TelevisionChannel, - last_channel: Option, - last_channel_results: Vec, + guide: TelevisionChannel, current_pattern: String, pub mode: Mode, input: Input, @@ -75,6 +71,7 @@ impl Television { #[must_use] pub fn new(mut channel: TelevisionChannel) -> Self { channel.find(EMPTY_STRING); + let guide = TelevisionChannel::TvGuide(TvGuide::new()); let spinner = Spinner::default(); let spinner_state = SpinnerState::from(&spinner); @@ -83,8 +80,7 @@ impl Television { action_tx: None, config: Config::default(), channel, - last_channel: None, - last_channel_results: Vec::new(), + guide, current_pattern: EMPTY_STRING.to_string(), mode: Mode::Channel, input: Input::new(EMPTY_STRING.to_string()), @@ -102,6 +98,7 @@ impl Television { } } + /// FIXME: this needs rework pub fn change_channel(&mut self, channel: TelevisionChannel) { self.reset_preview_scroll(); self.reset_results_selection(); @@ -111,33 +108,39 @@ impl Television { self.channel = channel; } - const MAX_BACKUP_RESULTS: u32 = 1000; - - fn backup_current_channel(&mut self) { - self.last_channel = Some(UnitChannel::from(&self.channel)); - self.last_channel_results = self.channel.results( - self.channel.result_count().min(Self::MAX_BACKUP_RESULTS), - 0, - ); - } - fn find(&mut self, pattern: &str) { - self.channel.find(pattern); + match self.mode { + Mode::Channel => { + self.channel.find(pattern); + } + Mode::Guide | Mode::SendToChannel => { + self.guide.find(pattern); + } + } } #[must_use] - pub fn get_selected_entry(&self) -> Option { - self.picker_state - .selected() - .and_then(|i| self.channel.get_result(u32::try_from(i).unwrap())) + pub fn get_selected_entry(&mut self) -> Option { + self.picker_state.selected().and_then(|i| match self.mode { + Mode::Channel => { + self.channel.get_result(u32::try_from(i).unwrap()) + } + Mode::Guide | Mode::SendToChannel => { + self.guide.get_result(u32::try_from(i).unwrap()) + } + }) } pub fn select_prev_entry(&mut self) { - if self.channel.result_count() == 0 { + let result_count = match self.mode { + Mode::Channel => self.channel.result_count(), + Mode::Guide | Mode::SendToChannel => self.guide.total_count(), + }; + if result_count == 0 { return; } let new_index = (self.picker_state.selected().unwrap_or(0) + 1) - % self.channel.result_count() as usize; + % result_count as usize; self.picker_state.select(Some(new_index)); if new_index == 0 { self.picker_view_offset = 0; @@ -163,7 +166,11 @@ impl Television { } pub fn select_next_entry(&mut self) { - if self.channel.result_count() == 0 { + let result_count = match self.mode { + Mode::Channel => self.channel.result_count(), + Mode::Guide | Mode::SendToChannel => self.guide.total_count(), + }; + if result_count == 0 { return; } let selected = self.picker_state.selected().unwrap_or(0); @@ -178,14 +185,11 @@ impl Television { self.picker_view_offset.saturating_sub(1); } } else { - self.picker_view_offset = self - .channel - .result_count() + self.picker_view_offset = result_count .saturating_sub(self.results_area_height - 2) as usize; - self.picker_state.select(Some( - (self.channel.result_count() as usize).saturating_sub(1), - )); + self.picker_state + .select(Some((result_count as usize).saturating_sub(1))); self.relative_picker_state .select(Some(self.results_area_height as usize - 3)); } @@ -301,24 +305,14 @@ impl Television { Action::ScrollPreviewHalfPageDown => self.scroll_preview_down(20), Action::ScrollPreviewHalfPageUp => self.scroll_preview_up(20), Action::ToggleChannelSelection => { - // TODO: continue this match self.mode { - // if we're in channel mode, backup current channel and - // switch to channel selection Mode::Channel => { - self.backup_current_channel(); - self.mode = Mode::ChannelSelection; - self.change_channel(TelevisionChannel::Channel( - SelectionChannel::new(), - )); + self.reset_screen(); + self.mode = Mode::Guide; } - // if we're in channel selection, switch to channel mode - // and restore the last channel if there is one - Mode::ChannelSelection => { + Mode::Guide => { + self.reset_screen(); self.mode = Mode::Channel; - if let Some(last_channel) = self.last_channel.take() { - self.change_channel(last_channel.into()); - } } Mode::SendToChannel => {} } @@ -331,7 +325,7 @@ impl Television { .as_ref() .unwrap() .send(Action::SelectAndExit)?, - Mode::ChannelSelection => { + Mode::Guide => { if let Ok(new_channel) = TelevisionChannel::try_from(&entry) { @@ -339,18 +333,38 @@ impl Television { self.change_channel(new_channel); } } - Mode::SendToChannel => {} + Mode::SendToChannel => { + // if let Ok(new_channel) = + // UnitChannel::try_from(&entry) + // { + // } + self.reset_screen(); + self.mode = Mode::Channel; + // TODO: spawn new channel with selected entries + } } } } Action::SendToChannel => { - if let Some(entry) = self.get_selected_entry() {} + self.mode = Mode::SendToChannel; + // TODO: build new guide from current channel based on which are pipeable into + self.guide = TelevisionChannel::TvGuide(TvGuide::new()); + self.reset_screen(); } _ => {} } Ok(None) } + fn reset_screen(&mut self) { + self.reset_preview_scroll(); + self.reset_results_selection(); + self.current_pattern = EMPTY_STRING.to_string(); + self.input.reset(); + self.channel.find(EMPTY_STRING); + self.guide.find(EMPTY_STRING); + } + /// Render the television on the screen. /// /// # Arguments @@ -362,16 +376,14 @@ impl Television { pub fn draw(&mut self, f: &mut Frame, area: Rect) -> Result<()> { let dimensions = match self.mode { Mode::Channel => &Dimensions::default(), - Mode::ChannelSelection | Mode::SendToChannel => { - &Dimensions::new(30, 70) - } + Mode::Guide | Mode::SendToChannel => &Dimensions::new(30, 70), }; let layout = Layout::build( dimensions, area, match self.mode { Mode::Channel => true, - Mode::ChannelSelection | Mode::SendToChannel => false, + Mode::Guide | Mode::SendToChannel => false, }, ); @@ -407,17 +419,26 @@ impl Television { .style(Style::default()) .padding(Padding::right(1)); - if self.channel.result_count() > 0 - && self.picker_state.selected().is_none() - { + let result_count = match self.mode { + Mode::Channel => self.channel.result_count(), + Mode::Guide | Mode::SendToChannel => self.guide.total_count(), + }; + if result_count > 0 && self.picker_state.selected().is_none() { self.picker_state.select(Some(0)); self.relative_picker_state.select(Some(0)); } - let entries = self.channel.results( - (layout.results.height.saturating_sub(2)).into(), - u32::try_from(self.picker_view_offset)?, - ); + let entries = match self.mode { + Mode::Channel => self.channel.results( + layout.results.height.saturating_sub(2).into(), + u32::try_from(self.picker_view_offset)?, + ), + Mode::Guide | Mode::SendToChannel => self.guide.results( + layout.results.height.saturating_sub(2).into(), + u32::try_from(self.picker_view_offset)?, + ), + }; + let results_list = build_results_list(results_block, &entries); f.render_stateful_widget( @@ -443,6 +464,10 @@ impl Television { f.render_widget(input_block, layout.input); // split input block into 3 parts: prompt symbol, input, result count + let total_count = match self.mode { + Mode::Channel => self.channel.total_count(), + Mode::Guide | Mode::SendToChannel => self.guide.total_count(), + }; let inner_input_chunks = RatatuiLayout::default() .direction(Direction::Horizontal) .constraints([ @@ -452,10 +477,7 @@ impl Television { Constraint::Fill(1), // result count Constraint::Length( - 3 * ((self.channel.total_count() as f32).log10().ceil() - as u16 - + 1) - + 3, + 3 * ((total_count as f32).log10().ceil() as u16 + 1) + 3, ), // spinner Constraint::Length(1), @@ -467,7 +489,7 @@ impl Television { "> ", Style::default().fg(DEFAULT_INPUT_FG).bold(), )) - .block(arrow_block); + .block(arrow_block); f.render_widget(arrow, inner_input_chunks[0]); let interactive_input_block = Block::default(); @@ -481,7 +503,10 @@ impl Television { .alignment(Alignment::Left); f.render_widget(input, inner_input_chunks[1]); - if self.channel.running() { + if match self.mode { + Mode::Channel => self.channel.running(), + Mode::Guide | Mode::SendToChannel => self.guide.running(), + } { f.render_stateful_widget( self.spinner, inner_input_chunks[3], @@ -490,21 +515,21 @@ impl Television { } let result_count_block = Block::default(); - let result_count = Paragraph::new(Span::styled( + let result_count_paragraph = Paragraph::new(Span::styled( format!( " {} / {} ", - if self.channel.result_count() == 0 { + if result_count == 0 { 0 } else { self.picker_state.selected().unwrap_or(0) + 1 }, - self.channel.result_count(), + result_count, ), Style::default().fg(DEFAULT_RESULTS_COUNT_FG).italic(), )) - .block(result_count_block) - .alignment(Alignment::Right); - f.render_widget(result_count, inner_input_chunks[2]); + .block(result_count_block) + .alignment(Alignment::Right); + f.render_widget(result_count_paragraph, inner_input_chunks[2]); // Make the cursor visible and ask tui-rs to put it at the // specified coordinates after rendering @@ -512,8 +537,8 @@ impl Television { // Put cursor past the end of the input text inner_input_chunks[1].x + u16::try_from( - self.input.visual_cursor().max(scroll) - scroll, - )?, + self.input.visual_cursor().max(scroll) - scroll, + )?, // Move one line down, from the border to the input line inner_input_chunks[1].y, )); diff --git a/crates/television/ui/help.rs b/crates/television/ui/help.rs index 7313c7e..83c15bd 100644 --- a/crates/television/ui/help.rs +++ b/crates/television/ui/help.rs @@ -20,9 +20,7 @@ impl Television { pub fn build_help_paragraph<'a>(&self) -> Result> { match self.mode { Mode::Channel => self.build_help_paragraph_for_channel(), - Mode::ChannelSelection => { - self.build_help_paragraph_for_channel_selection() - } + Mode::Guide => self.build_help_paragraph_for_channel_selection(), Mode::SendToChannel => self.build_help_paragraph_for_channel(), } } @@ -53,16 +51,6 @@ impl Television { ns_line.extend(preview_spans); ns_line.push_span(Span::styled(SEPARATOR, Style::default())); - // Send to channel - let send_to_channel_keys = - keys_for_action(keymap, Action::SendToChannel); - // TODO: add send icon - let send_to_channel_spans = - build_spans_for_key_groups("Send to", vec![send_to_channel_keys]); - - ns_line.extend(send_to_channel_spans); - ns_line.push_span(Span::styled(SEPARATOR, Style::default())); - // Select entry let select_entry_keys = keys_for_action(keymap, Action::SelectEntry); let select_entry_spans = build_spans_for_key_groups( @@ -73,6 +61,16 @@ impl Television { ns_line.extend(select_entry_spans); ns_line.push_span(Span::styled(SEPARATOR, Style::default())); + // Send to channel + let send_to_channel_keys = + keys_for_action(keymap, Action::SendToChannel); + // TODO: add send icon + let send_to_channel_spans = + build_spans_for_key_groups("Send to", vec![send_to_channel_keys]); + + ns_line.extend(send_to_channel_spans); + ns_line.push_span(Span::styled(SEPARATOR, Style::default())); + // Switch channels let switch_channels_keys = keys_for_action(keymap, Action::ToggleChannelSelection); @@ -135,7 +133,7 @@ impl Television { ); ns_line.extend(switch_channels_spans); - + lines.push(ns_line); // MISC line (quit, help, etc.) diff --git a/crates/television/utils/files.rs b/crates/television/utils/files.rs index 714cc63..123db63 100644 --- a/crates/television/utils/files.rs +++ b/crates/television/utils/files.rs @@ -1,5 +1,5 @@ -use std::collections::HashSet; use std::path::Path; +use std::{collections::HashSet, path::PathBuf}; use ignore::{overrides::Override, types::TypesBuilder, WalkBuilder}; use infer::Infer; @@ -15,6 +15,7 @@ pub fn walk_builder( path: &Path, n_threads: usize, overrides: Option, + ignore_paths: Option>, ) -> WalkBuilder { let mut builder = WalkBuilder::new(path); @@ -23,6 +24,13 @@ pub fn walk_builder( types_builder.add_defaults(); builder.types(types_builder.build().unwrap()); + // ignore paths + if let Some(paths) = ignore_paths { + for path in paths { + builder.add_ignore(path); + } + } + builder.threads(n_threads); if let Some(ov) = overrides { builder.overrides(ov); diff --git a/crates/television_derive/src/lib.rs b/crates/television_derive/src/lib.rs index f6fd831..b830aa7 100644 --- a/crates/television_derive/src/lib.rs +++ b/crates/television_derive/src/lib.rs @@ -11,7 +11,7 @@ pub fn cli_channel_derive(input: TokenStream) -> TokenStream { impl_cli_channel(&ast) } -const VARIANT_BLACKLIST: [&str; 2] = ["Stdin", "Channel"]; +const VARIANT_BLACKLIST: [&str; 2] = ["Stdin", "TvGuide"]; fn impl_cli_channel(ast: &syn::DeriveInput) -> TokenStream { // check that the struct is an enum @@ -180,7 +180,7 @@ fn impl_tv_channel(ast: &syn::DeriveInput) -> TokenStream { )* } } - + fn shutdown(&self) { match self { #( @@ -244,7 +244,7 @@ fn impl_unit_channel(ast: &syn::DeriveInput) -> TokenStream { } } }; - + // Generate From<&TelevisionChannel> implementation let from_impl = quote! { impl From<&TelevisionChannel> for UnitChannel {