diff options
author | Thang Pham <phamducthang1234@gmail.com> | 2021-06-12 12:38:31 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-12 12:38:31 +0900 |
commit | 46ac43b1f5be948086a3ea65d6086ca3cdec5106 (patch) | |
tree | f653e1c1bdf4f47db6d62afbc955c6a3c04d667e | |
parent | 19f3eba419ebd65c7152ffbcc904eef2af8822a4 (diff) |
Implement `config_parser` crates to allow optional configurations (#39)
-rw-r--r-- | Cargo.lock | 126 | ||||
-rw-r--r-- | Cargo.toml | 34 | ||||
-rw-r--r-- | README.md | 19 | ||||
-rw-r--r-- | config_parser/Cargo.toml | 10 | ||||
-rw-r--r-- | config_parser/src/lib.rs | 37 | ||||
-rw-r--r-- | config_parser/tests/test.rs | 107 | ||||
-rw-r--r-- | config_parser_derive/Cargo.lock | 76 | ||||
-rw-r--r-- | config_parser_derive/Cargo.toml | 13 | ||||
-rw-r--r-- | config_parser_derive/src/lib.rs | 13 | ||||
-rw-r--r-- | config_parser_derive/src/parser.rs | 44 | ||||
-rw-r--r-- | hackernews_tui/Cargo.lock | 1264 | ||||
-rw-r--r-- | hackernews_tui/Cargo.toml | 35 | ||||
-rw-r--r-- | hackernews_tui/src/config.rs (renamed from src/config.rs) | 40 | ||||
-rw-r--r-- | hackernews_tui/src/hn-tui-default.toml (renamed from src/hn-tui-default.toml) | 17 | ||||
-rw-r--r-- | hackernews_tui/src/hn_client.rs (renamed from src/hn_client.rs) | 5 | ||||
-rw-r--r-- | hackernews_tui/src/keybindings.rs (renamed from src/keybindings.rs) | 17 | ||||
-rw-r--r-- | hackernews_tui/src/main.rs (renamed from src/main.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/prelude.rs (renamed from src/prelude.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/utils.rs (renamed from src/utils.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/article_view.rs (renamed from src/view/article_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/async_view.rs (renamed from src/view/async_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/comment_view.rs (renamed from src/view/comment_view.rs) | 6 | ||||
-rw-r--r-- | hackernews_tui/src/view/error_view.rs (renamed from src/view/error_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/fn_view_wrapper.rs (renamed from src/view/fn_view_wrapper.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/help_view.rs (renamed from src/view/help_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/list_view.rs (renamed from src/view/list_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/mod.rs (renamed from src/view/mod.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/search_view.rs (renamed from src/view/search_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/story_view.rs (renamed from src/view/story_view.rs) | 0 | ||||
-rw-r--r-- | hackernews_tui/src/view/text_view.rs (renamed from src/view/text_view.rs) | 0 | ||||
-rwxr-xr-x | run_debug | 2 |
31 files changed, 1727 insertions, 138 deletions
@@ -72,15 +72,15 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bumpalo" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "cc" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" [[package]] name = "cfg-if" @@ -123,10 +123,28 @@ dependencies = [ ] [[package]] +name = "config_parser" +version = "0.1.0" +dependencies = [ + "config_parser_derive", + "serde", + "toml", +] + +[[package]] +name = "config_parser_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "crossbeam" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" dependencies = [ "cfg-if", "crossbeam-channel", @@ -159,9 +177,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ "cfg-if", "crossbeam-utils", @@ -172,9 +190,9 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756" +checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" dependencies = [ "cfg-if", "crossbeam-utils", @@ -182,11 +200,10 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", "cfg-if", "lazy_static", ] @@ -230,7 +247,7 @@ dependencies = [ "lazy_static", "libc", "log", - "signal-hook 0.3.8", + "signal-hook 0.3.9", "unicode-segmentation", "unicode-width", "wasmer_enumset", @@ -417,9 +434,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", @@ -432,6 +449,7 @@ version = "0.6.2" dependencies = [ "anyhow", "clap", + "config_parser", "cursive", "cursive-aligned-view", "cursive-async-view", @@ -480,9 +498,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -512,9 +530,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" +checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" dependencies = [ "wasm-bindgen", ] @@ -527,15 +545,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "lock_api" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" dependencies = [ "scopeguard", ] @@ -563,9 +581,9 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memoffset" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -735,9 +753,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] @@ -778,9 +796,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" dependencies = [ "bitflags", ] @@ -829,9 +847,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ "base64", "log", @@ -912,9 +930,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" dependencies = [ "libc", "signal-hook-registry", @@ -922,9 +940,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] @@ -970,9 +988,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" dependencies = [ "proc-macro2", "quote", @@ -1042,9 +1060,9 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] @@ -1063,9 +1081,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "untrusted" @@ -1123,9 +1141,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" +checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1133,9 +1151,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" +checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" dependencies = [ "bumpalo", "lazy_static", @@ -1148,9 +1166,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" +checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1158,9 +1176,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" +checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" dependencies = [ "proc-macro2", "quote", @@ -1171,9 +1189,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" +checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" [[package]] name = "wasmer_enumset" @@ -1199,9 +1217,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" +checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" dependencies = [ "js-sys", "wasm-bindgen", @@ -1,33 +1,3 @@ -[package] -name = "hackernews_tui" -version = "0.6.2" -authors = ["Thang Pham <phamducthang1234@gmail.com>"] -edition = "2018" -license = "MIT" -description = "A Terminal UI to browse Hacker News" -repository = "https://github.com/aome510/hackernews-TUI" -keywords = ["hackernews", "tui"] -readme = "README.md" -include = ["src/**/*", "LICENSE", "README.*", "!**/examples/**/*"] +[workspace] -[dependencies] -cursive = { version = "0.16.3", default-features = false, features = ["crossterm-backend"] } -cursive-async-view = "0.5.0" -cursive_buffered_backend = "0.5.0" -cursive-aligned-view = "0.4.0" - -ureq = { version = "2.1.1", features = ["json"] } -serde = { version = "1.0.126", features = ["derive"] } -serde_json = "1.0.64" -anyhow = "1.0.40" -rayon = "1.5.1" -log = "0.4.14" -env_logger = "0.8.3" -htmlescape = "0.3.1" -regex = "1.5.4" -substring = "1.4.5" -once_cell = "1.7.2" -toml = "0.5.8" -clap = "2.33.3" -dirs-next = "2.0.0" -url = "2.2.2" +members = ["hackernews_tui", "config_parser", "config_parser_derive"] @@ -210,23 +210,15 @@ Key shortcuts: ## Configuration -By default, the application will look for `~/.config/hn-tui.toml` as its configuration file. +By default, the application will look for `~/.config/hn-tui.toml` as the configuration file. -You can specify the path by specifying the `-c` or `--config` argument when running the application: +You can also specify the path with the `-c` or `--config` option when running the application: ```shell hackernews_tui -c ~/.config/hn-tui.toml ``` -For further information about the config options, please refer to the example config file by running `hackernews_tui --example-config`. - -**Note**: all config options (as included in the example config file) are **required**. You can run - -```shell -hackernews_tui --example-config > ~/.config/hn-tui.toml -``` - -then modify the config options in `~/.config/hn-tui.toml` based on your preferences. +For further information about the configuration options, please refer to the example configuration file by running `hackernews_tui --example-config`. ### Article Parse Command @@ -258,11 +250,11 @@ An alternative is to use [`article_md`](https://github.com/aome510/article-md-cl ### User-defined shortcuts -Shortcuts in each `View` are fully customizable, for further information about the supported keys and the corresponding functionalities, please refer to the **user-defined key bindings** sections in the example config file by running `hackernews_tui --example-config`. +Shortcuts in each `View` are fully customizable. For further information about the supported keys and the commands, please refer to the **user-defined key bindings** sections in the example configuration file by running `hackernews_tui --example-config`. ### Custom Keymap -It's possible to define a custom shortcut to switch between different kinds of `StoryView` (`front_page`, `show_hn`, `ask_hn`, etc) with stories filtered by HN Algolia's [`numericFilters`](https://hn.algolia.com/api/). An example of defining such a custom shortcut can be found under the **Custom Keymap** section of the example configuration file. +It's possible to define a custom shortcut to switch between different `StoryView` (`front_page`, `show_hn`, `ask_hn`, etc) with stories filtered by HN Algolia's [`numericFilters`](https://hn.algolia.com/api/). An example of defining such custom shortcuts can be found under the **custom keymap** section of the example configuration file. ## Debug @@ -279,6 +271,7 @@ to view the application's log in `log.txt` file. - [x] make all commands customizable - [x] add a `View` to read the linked story in reader mode on the terminal. A list of possible suggestion can be found [here](https://news.ycombinator.com/item?id=26930466) - [ ] add commands to navigate parent comments and collapse a comment +- [x] make all the configuration options optional - integrate [HackerNews Official APIs](https://github.com/HackerNews/API) for real-time updating, lazy-loading comments, and sorting stories - [x] lazy-loading comments - [x] front-page stories like the official site diff --git a/config_parser/Cargo.toml b/config_parser/Cargo.toml new file mode 100644 index 0000000..3aca09b --- /dev/null +++ b/config_parser/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "config_parser" +version = "0.1.0" +authors = ["Thang Pham <phamducthang1234@gmail.com>"] +edition = "2018" + +[dependencies] +toml = "0.5.8" +config_parser_derive = { path = "../config_parser_derive" } +serde = { version = "1.0.126", features = ["derive"] } diff --git a/config_parser/src/lib.rs b/config_parser/src/lib.rs new file mode 100644 index 0000000..6e5bfad --- /dev/null +++ b/config_parser/src/lib.rs @@ -0,0 +1,37 @@ +pub trait ConfigParser { + fn parse(&mut self, value: toml::Value); +} + +pub use config_parser_derive::ConfigParse; + +#[macro_export] +macro_rules! config_parser_impl { + ($($t:ty),+) => { + $( + impl ConfigParser for $t { + fn parse(&mut self, value: toml::Value) { + *self = value.try_into::<$t>().unwrap(); + } + } + )* + }; +} + +impl<T: ConfigParser + Default> ConfigParser for Vec<T> { + fn parse(&mut self, value: toml::Value) { + if let toml::Value::Array(array) = value { + *self = array + .into_iter() + .map(|e| { + let mut v = T::default(); + v.parse(e); + v + }) + .collect::<Vec<_>>(); + } + } +} + +config_parser_impl!( + String, usize, u128, u64, u32, u16, u8, isize, i128, i64, i32, i16, i8, f64, f32, bool, char +); diff --git a/config_parser/tests/test.rs b/config_parser/tests/test.rs new file mode 100644 index 0000000..5c808c1 --- /dev/null +++ b/config_parser/tests/test.rs @@ -0,0 +1,107 @@ +use config_parser_derive::ConfigParser; +use serde::Deserialize; + +#[derive(ConfigParser, Deserialize, Default, Debug, PartialEq)] +struct A { + pub field_1: String, + pub field_2: u32, + pub field_3: bool, + pub field_4: Vec<B>, + pub field_5: C, +} + +#[derive(ConfigParser, Deserialize, Default, Debug, PartialEq)] +struct B { + pub field_1: String, + pub field_2: String, +} + +#[derive(ConfigParser, Deserialize, Default, Debug, PartialEq)] +struct C { + pub field_1: B, + pub field_2: bool, + pub field_3: bool, +} + +#[cfg(test)] +mod tests { + use super::*; + use config_parser::ConfigParser; + + #[test] + fn simple_test() { + let value = "a = ['b', 'c', 'd']".parse::<toml::Value>().unwrap(); + let mut a: Vec<String> = vec![]; + a.parse(value["a"].clone()); + assert!(a.len() == 3); + } + + #[test] + fn complex_test() { + let mut value = A { + field_1: "field_1".to_owned(), + field_2: 510, + field_3: false, + field_4: vec![B { + field_1: "b_field_1".to_owned(), + field_2: "b_field_2".to_owned(), + }], + field_5: C { + field_1: B { + field_1: "cb_field_1".to_owned(), + field_2: "cb_field_2".to_owned(), + }, + field_2: true, + field_3: false, + }, + }; + + let toml = " +field_1 = 'new_field_1' +field_2 = 150 + +[[field_4]] +field_2 = 'new_field_2' + +[[field_4]] +field_1 = 'new_field_1' + +[field_5.field_1] +field_1 = 'new_field_1' +field_2 = 'new_field_2' + +[field_5] +field_2 = false +field_3 = true +" + .parse::<toml::Value>() + .unwrap(); + + let expected_value = A { + field_1: "new_field_1".to_owned(), + field_2: 150, + field_3: false, + field_4: vec![ + B { + field_1: "".to_owned(), + field_2: "new_field_2".to_owned(), + }, + B { + field_1: "new_field_1".to_owned(), + field_2: "".to_owned(), + }, + ], + field_5: C { + field_1: B { + field_1: "new_field_1".to_owned(), + field_2: "new_field_2".to_owned(), + }, + field_2: false, + field_3: true, + }, + }; + + value.parse(toml); + assert!(value == expected_value); + } +} diff --git a/config_parser_derive/Cargo.lock b/config_parser_derive/Cargo.lock new file mode 100644 index 0000000..a5b3524 --- /dev/null +++ b/config_parser_derive/Cargo.lock @@ -0,0 +1,76 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "config_parser" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/config_parser_derive/Cargo.toml b/config_parser_derive/Cargo.toml new file mode 100644 index 0000000..2e99934 --- /dev/null +++ b/config_parser_derive/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "config_parser_derive" +version = "0.1.0" +authors = ["Thang Pham <phamducthang1234@gmail.com>"] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.27" +quote = "1.0.9" +syn = "1.0.72" diff --git a/config_parser_derive/src/lib.rs b/config_parser_derive/src/lib.rs new file mode 100644 index 0000000..04e06ff --- /dev/null +++ b/config_parser_derive/src/lib.rs @@ -0,0 +1,13 @@ +use proc_macro::TokenStream; +use syn::{parse_macro_input, DeriveInput}; + +mod parser; +use parser::expand_config_parsers; + +#[proc_macro_derive(ConfigParse)] +pub fn parsers(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + expand_config_parsers(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/config_parser_derive/src/parser.rs b/config_parser_derive/src/parser.rs new file mode 100644 index 0000000..6e7a781 --- /dev/null +++ b/config_parser_derive/src/parser.rs @@ -0,0 +1,44 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{Data, DataStruct, DeriveInput, Fields}; + +pub fn expand_config_parsers(input: DeriveInput) -> syn::Result<TokenStream> { + let fields = match input.data { + Data::Struct(DataStruct { + fields: Fields::Named(fields), + .. + }) => fields.named, + _ => panic!("this derive macro only works on structs with named fields"), + }; + + let parsers = fields + .into_iter() + .map(|f| { + let field_name_str = f.ident.as_ref().unwrap().to_string(); + let field_name = f.ident; + + Ok(quote! { + #field_name_str => { + self.#field_name.parse(value); + } + }) + }) + .collect::<syn::Result<TokenStream>>()?; + + let st_name = input.ident; + Ok(quote! { + #[automatically_derived] + impl config_parser::ConfigParser for #st_name { + fn parse(&mut self, value: toml::Value) { + if let(toml::Value::Table(table)) = value { + table.into_iter().for_each(|(key, value)| { + match key.as_str() { + #parsers + _ => {} + }; + }); + } + } + } + }) +} diff --git a/hackernews_tui/Cargo.lock b/hackernews_tui/Cargo.lock new file mode 100644 index 0000000..01ef524 --- /dev/null +++ b/hackernews_tui/Cargo.lock @@ -0,0 +1,1264 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ahash" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" + +[[package]] +name = "array-macro" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e97b4e522f9e55523001238ac59d13a8603af57f69980de5d8de4bbbe8ada6" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" |