diff --git a/Cargo.lock b/Cargo.lock index 7da63f13..f80cfee2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,7 +254,7 @@ checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.4", "num-traits 0.2.16", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -290,7 +290,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -351,7 +351,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", "synstructure", @@ -363,7 +363,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -434,9 +434,9 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -445,9 +445,9 @@ version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -692,7 +692,7 @@ dependencies = [ "borsh-derive-internal 0.9.3", "borsh-schema-derive-internal 0.9.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "syn 1.0.109", ] @@ -705,7 +705,7 @@ dependencies = [ "borsh-derive-internal 0.10.3", "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "syn 1.0.109", ] @@ -715,7 +715,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -726,7 +726,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -737,7 +737,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -748,7 +748,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -821,9 +821,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -927,7 +927,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" dependencies = [ "clap_builder", - "clap_derive", ] [[package]] @@ -942,18 +941,6 @@ dependencies = [ "strsim 0.10.0", ] -[[package]] -name = "clap_derive" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" -dependencies = [ - "heck", - "proc-macro2 1.0.66", - "quote 1.0.33", - "syn 2.0.31", -] - [[package]] name = "clap_lex" version = "0.2.4" @@ -997,6 +984,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "config_parser" +version = "0.1.0" +dependencies = [ + "proc-macro2 1.0.69", + "quote 1.0.33", + "syn 2.0.39", +] + [[package]] name = "console" version = "0.15.7" @@ -1051,7 +1047,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a4f51209740b5e1589e702b3044cdd4562cef41b6da404904192ffffb852d62" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -1242,10 +1238,10 @@ checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "strsim 0.10.0", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -1256,7 +1252,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -1319,7 +1315,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -1331,7 +1327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "rustc_version", "syn 1.0.109", @@ -1396,9 +1392,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -1507,9 +1503,9 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -1676,9 +1672,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -2295,7 +2291,7 @@ checksum = "d814a21d9a819f8de1a41b819a263ffd68e4bb5f043d936db1c49b54684bde0a" dependencies = [ "heck", "proc-macro-crate 1.3.1", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -2446,6 +2442,7 @@ dependencies = [ "bytes", "chrono", "clap 4.4.2", + "config_parser", "const_env", "dashmap", "dotenv", @@ -2700,7 +2697,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", ] @@ -2711,9 +2708,9 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -2802,9 +2799,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -2814,9 +2811,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -2876,9 +2873,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -3031,9 +3028,9 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -3144,8 +3141,8 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ - "proc-macro2 1.0.66", - "syn 2.0.31", + "proc-macro2 1.0.69", + "syn 2.0.39", ] [[package]] @@ -3178,9 +3175,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -3227,7 +3224,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.31", + "syn 2.0.39", "tempfile", "which", ] @@ -3240,9 +3237,9 @@ checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -3343,7 +3340,7 @@ version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", ] [[package]] @@ -3772,9 +3769,9 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -3846,16 +3843,16 @@ version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -3891,9 +3888,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -4234,10 +4231,10 @@ version = "1.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dfe18c5155015dcb494c6de84a03b725fcf90ec2006a047769018b94c2cf0de" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "rustc_version", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -4822,10 +4819,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e560806a3859717eb2220b26e2cd68bb757b63affa3e79c3f1d8d853b5ee78f" dependencies = [ "bs58", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "rustversion", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5079,7 +5076,7 @@ checksum = "fadbefec4f3c678215ca72bd71862697bb06b41fd77c0088902dd3203354387b" dependencies = [ "quote 1.0.33", "spl-discriminator-syn", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5088,10 +5085,10 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e5f2044ca42c8938d54d1255ce599c79a1ffd86b677dfab695caa20f9ffc3f2" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "sha2 0.10.7", - "syn 2.0.31", + "syn 2.0.39", "thiserror", ] @@ -5145,10 +5142,10 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5269c8e868da17b6552ef35a51355a017bd8e0eae269c201fef830d35fa52c" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "sha2 0.10.7", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5290,18 +5287,18 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.31" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "unicode-ident", ] @@ -5318,7 +5315,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", "syn 1.0.109", "unicode-xid 0.2.4", @@ -5376,9 +5373,9 @@ version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5499,9 +5496,9 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5668,10 +5665,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" dependencies = [ "prettyplease", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "prost-build", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5738,9 +5735,9 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] @@ -5989,9 +5986,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", "wasm-bindgen-shared", ] @@ -6023,9 +6020,9 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6382,9 +6379,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.66", + "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.31", + "syn 2.0.39", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be24c5bf..b34dd385 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,8 @@ members = [ "quic-forward-proxy-integration-test", "cluster-endpoints", "history", - "bench" + "bench", + "./config_parser", ] [workspace.package] @@ -39,7 +40,7 @@ futures = "0.3.28" bytes = "1.4.0" anyhow = "1.0.70" log = "0.4.17" -clap = { version = "4.2.4", features = ["derive", "env"] } +clap = { version = "4.2.4", features = ["env", "cargo"] } dashmap = "5.4.0" const_env = "0.1.2" jsonrpsee = { version = "0.17.0", features = ["macros", "full"] } diff --git a/config_parser/Cargo.toml b/config_parser/Cargo.toml new file mode 100644 index 00000000..5f0b00f5 --- /dev/null +++ b/config_parser/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "config_parser" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.69" +quote = "1.0.33" +syn = "2.0.39" diff --git a/config_parser/src/lib.rs b/config_parser/src/lib.rs new file mode 100644 index 00000000..16448a71 --- /dev/null +++ b/config_parser/src/lib.rs @@ -0,0 +1,217 @@ +use proc_macro::TokenStream; +use quote::{quote, ToTokens}; +use syn::{Data, Expr}; + +struct Arg<'a> { + name: &'a syn::Ident, + ty: &'a syn::Type, + desc: Option, + default: Option, + short: Option, + long: Option, +} + +#[proc_macro_derive(ConfigParser, attributes(arg))] +pub fn config_parser(input: TokenStream) -> TokenStream { + let input = syn::parse::(input).unwrap(); + + let name = input.ident; + + let Data::Struct(ref data) = input.data else { + panic!("expected struct"); + }; + + // get the fields and attributes + let args = data + .fields + .iter() + .map(|field| { + let name = field.ident.as_ref().expect("expected field name"); + + let mut arg = Arg { + name, + ty: &field.ty, + desc: None, + default: None, + short: None, + long: None, + }; + + field + .attrs + .iter() + .find(|attr| attr.path().is_ident("arg")) + .expect("expected arg attribute") + .parse_nested_meta(|meta| { + let value = meta + .value() + .map(|value| value.parse::().unwrap()) + .ok(); + + if meta.path.is_ident("default") { + arg.default = Some(value.expect("expected default value")); + } else if meta.path.is_ident("short") { + arg.short = Some(value.unwrap_or_else(|| { + let c = arg.name.to_string().chars().next().unwrap(); + syn::parse(quote!(#c).into()).unwrap() + })); + } else if meta.path.is_ident("long") { + arg.long = Some( + value.unwrap_or_else(|| syn::parse(quote!(#name).into()).unwrap()), + ); + } else if meta.path.is_ident("desc") { + arg.desc = value; + } else { + panic!("unknown arg attribute"); + } + + Ok(()) + }) + .expect("expected arg attribute to be a list of key-value pairs"); + + if arg.name == "config" && arg.default.is_none() { + panic!("config must have a default value"); + } + + arg + }) + .collect::>(); + + // default config path + let config_default = args + .iter() + .find(|arg| arg.name == "config") + .expect("config arg must be present") + .default + .as_ref() + .unwrap(); + + let arg_matches = args.iter().map(|arg| { + let short = arg + .short + .as_ref() + .map(|short| quote!(-#short)) + .unwrap_or_else(|| quote! {}); + + let long = arg + .long + .as_ref() + .map(|long| quote!(--#long)) + .unwrap_or_else(|| quote! {}); + + let val = if arg.ty.into_token_stream().to_string() == "bool" { + quote!() + } else { + let name = arg.name.to_string().to_uppercase(); + quote!(<#name>) + }; + + let desc = arg + .desc + .as_ref() + .map(|desc| quote!(#desc)) + .unwrap_or_else(|| quote! {String::new()}); + + let default = arg + .default + .as_ref() + .map(|default| quote!(format!("[default : {}]", #default))) + .unwrap_or_else(|| quote! {String::new()}); + + quote! { + arg! (#short #long #val) + .help(&format!("{} {}", #desc, #default)) + } + }); + + let assemble_args = args.iter().map(|arg| { + let name = arg.name; + let ty = arg.ty; + let default = if let Some(ref default) = arg.default { + quote! { + value.unwrap_or_else(|| #default) + } + } else { + quote! { + value.unwrap_or_default() + } + }; + + quote! { + #name: { + let name = stringify!(#name); + let value = matches.remove_one::<#ty>(name); + let value = value.or_else(|| { + config.as_ref().and_then(|config| { + config.get(name).and_then(|value| { + serde_json::from_value(value.clone()).ok() + }) + }) + }); + #default + } + } + }); + + quote! { + impl #name { + async fn check_if_config_exists>(path: P) -> anyhow::Result<()> { + // Check if file exists + if tokio::fs::metadata(&path).await.is_err() { + anyhow::bail!("Config file does not exist") + } + + Ok(()) + } + + async fn read_config>(path: P) -> anyhow::Result { + use tokio::io::AsyncReadExt; + + // Open the file + let mut file = tokio::fs::File::open(path).await?; + + // Read the contents + let mut contents = String::new(); + file.read_to_string(&mut contents).await?; + + // Parse the contents + Ok(serde_json::from_str(&contents)?) + } + + pub async fn parse() -> anyhow::Result { + use clap::{arg, command, value_parser, ArgAction, Command}; + use tokio::fs::File; + + // get matches + let mut matches = command!() // requires `cargo` feature + .args([ + #(#arg_matches,)* + ]) + .get_matches(); + + // get config path + let config_path: Option = matches.remove_one("config"); + let config_arg_provided = config_path.is_some(); + let config_path = config_path.unwrap_or(#config_default); + + let config = if Self::check_if_config_exists(&config_path).await.is_ok() { + Some(Self::read_config(&config_path).await?) + } else { + if config_arg_provided { + anyhow::bail!("Config file does not exist") + } else { + None + } + }; + + + Ok(Self { + #( + #assemble_args, + )* + }) + } + } + } + .into() +} diff --git a/lite-rpc/Cargo.toml b/lite-rpc/Cargo.toml index 192b6d9a..3706d82e 100644 --- a/lite-rpc/Cargo.toml +++ b/lite-rpc/Cargo.toml @@ -16,7 +16,7 @@ solana-rpc-client-api = { workspace = true } solana-transaction-status = { workspace = true } solana-version = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } +serde_json = "1.0.108" bincode = { workspace = true } bs58 = { workspace = true } base64 = { workspace = true } @@ -41,7 +41,7 @@ async-trait = { workspace = true } tokio = { version = "1.28.2", features = ["full", "fs"]} tokio-postgres = { version = "0.7.8", features = ["with-chrono-0_4"] } chrono = { workspace = true } - +config_parser = { path = "../config_parser" } solana-lite-rpc-core = { workspace = true } solana-lite-rpc-services = { workspace = true } solana-lite-rpc-cluster-endpoints = { workspace = true } diff --git a/lite-rpc/src/cli.rs b/lite-rpc/src/cli.rs index 9e9cfdae..aed7cb9b 100644 --- a/lite-rpc/src/cli.rs +++ b/lite-rpc/src/cli.rs @@ -2,40 +2,37 @@ use crate::{ DEFAULT_FANOUT_SIZE, DEFAULT_GRPC_ADDR, DEFAULT_RETRY_TIMEOUT, DEFAULT_RPC_ADDR, DEFAULT_WS_ADDR, MAX_RETRIES, }; -use clap::Parser; +use config_parser::ConfigParser; -#[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None)] +#[derive(ConfigParser, Clone)] pub struct Args { - #[arg(short, long, default_value_t = String::from(DEFAULT_RPC_ADDR))] + #[arg(short, long, default = String::from("config.json"))] + pub config: String, + #[arg(short, long, default = String::from(DEFAULT_RPC_ADDR))] pub rpc_addr: String, - #[arg(short, long, default_value_t = String::from(DEFAULT_WS_ADDR))] + #[arg(short, long, default = String::from(DEFAULT_WS_ADDR))] pub ws_addr: String, - #[arg(short = 'l', long, default_value_t = String::from("[::]:8890"))] + #[arg(short = 'l', long, default = String::from("[::]:8890"))] pub lite_rpc_http_addr: String, - #[arg(short = 's', long, default_value_t = String::from("[::]:8891"))] + #[arg(short = 's', long, default = String::from("[::]:8891"))] pub lite_rpc_ws_addr: String, - /// tpu fanout - #[arg(short = 'f', long, default_value_t = DEFAULT_FANOUT_SIZE) ] + #[arg(short = 'f', long, default = DEFAULT_FANOUT_SIZE, desc="tpu fanout") ] pub fanout_size: u64, - /// enable logging to postgres - #[arg(short = 'p', long)] + #[arg(short = 'p', long, desc = "enable logging to postgres")] pub enable_postgres: bool, - /// enable metrics to prometheus at addr - #[arg(short = 'm', long, default_value_t = String::from("[::]:9091"))] + #[arg(short = 'm', long, default = String::from("[::]:9091"), desc = "enable metrics to prometheus at addr")] pub prometheus_addr: String, - #[arg(short = 'k', long, default_value_t = String::new())] + #[arg(short = 'k', long, default = String::new())] pub identity_keypair: String, - #[arg(long, default_value_t = MAX_RETRIES)] + #[arg(long, default = MAX_RETRIES)] pub maximum_retries_per_tx: usize, - #[arg(long, default_value_t = DEFAULT_RETRY_TIMEOUT)] + #[arg(long, default = DEFAULT_RETRY_TIMEOUT)] pub transaction_retry_after_secs: u64, #[arg(long)] pub quic_proxy_addr: Option, #[arg(short = 'g', long)] pub use_grpc: bool, - /// grpc address - #[arg(long, default_value_t = String::from(DEFAULT_GRPC_ADDR))] + #[arg(long, default = String::from(DEFAULT_GRPC_ADDR), desc = "grpc address")] pub grpc_addr: String, #[arg(long)] pub grpc_x_token: Option, diff --git a/lite-rpc/src/main.rs b/lite-rpc/src/main.rs index e8b6e279..c7f821d7 100644 --- a/lite-rpc/src/main.rs +++ b/lite-rpc/src/main.rs @@ -3,7 +3,6 @@ pub mod rpc_tester; use std::time::Duration; use anyhow::bail; -use clap::Parser; use dashmap::DashMap; use dotenv::dotenv; use lite_rpc::postgres_logger::PostgresLogger; @@ -239,8 +238,8 @@ pub async fn start_lite_rpc(args: Args, rpc_client: Arc) -> anyhow::R } } -fn get_args() -> Args { - let mut args = Args::parse(); +async fn get_args() -> anyhow::Result { + let mut args = Args::parse().await?; dotenv().ok(); @@ -251,14 +250,14 @@ fn get_args() -> Args { false }; - args + Ok(args) } #[tokio::main(flavor = "multi_thread", worker_threads = 16)] pub async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); - let args = get_args(); + let args = get_args().await?; let ctrl_c_signal = tokio::signal::ctrl_c(); let Args { rpc_addr, .. } = &args;