diff options
Diffstat (limited to '')
77 files changed, 2691 insertions, 3961 deletions
@@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -43,15 +43,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arrayref" @@ -111,9 +111,31 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "aws-lc-rs" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] [[package]] name = "base64" @@ -123,9 +145,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bindgen" @@ -133,7 +155,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "cexpr", "clang-sys", "itertools", @@ -143,7 +165,7 @@ dependencies = [ "quote", "regex", "rustc-hash", - "shlex", + "shlex 1.3.0", "syn", ] @@ -155,24 +177,25 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" dependencies = [ "serde_core", ] [[package]] name = "blake3" -version = "1.8.2" +version = "1.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", + "cpufeatures 0.3.0", "serde", ] @@ -187,9 +210,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byteorder" @@ -199,18 +222,20 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.47" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", - "shlex", + "jobserver", + "libc", + "shlex 2.0.1", ] [[package]] @@ -229,10 +254,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] name = "chrono" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -263,9 +294,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -273,9 +304,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -285,21 +316,21 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.61" +version = "4.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" dependencies = [ "clap", "clap_lex", "is_executable", - "shlex", + "shlex 1.3.0", ] [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -309,19 +340,38 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "colors" -version = "1.8.0" +version = "1.9.0" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] [[package]] name = "concurrent-queue" @@ -340,9 +390,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "core-foundation" @@ -355,6 +405,16 @@ dependencies = [ ] [[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -370,6 +430,15 @@ dependencies = [ ] [[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] name = "crc" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -380,9 +449,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crossbeam" @@ -458,7 +527,7 @@ checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", "socket2", @@ -467,9 +536,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.84+curl-8.17.0" +version = "0.4.88+curl-8.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abc4294dc41b882eaff37973c2ec3ae203d0091341ee68fbadd1d06e0c18a73b" +checksum = "644816de6547255eff4e491a1dda1c19b7237f00b62a61e6e64859ce4f2906d0" dependencies = [ "cc", "libc", @@ -477,7 +546,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -511,9 +580,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -527,10 +596,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] @@ -584,15 +659,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "flume" @@ -618,21 +693,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -642,10 +702,16 @@ dependencies = [ ] [[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -658,9 +724,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -668,15 +734,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -696,15 +762,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -713,21 +779,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -737,7 +803,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -753,13 +818,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -769,9 +836,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", ] [[package]] @@ -782,9 +864,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "h2" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -812,9 +894,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" @@ -872,9 +954,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -911,9 +993,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.8.1" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -925,7 +1007,6 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -933,46 +1014,28 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", ] [[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] name = "hyper-util" -version = "0.1.18" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", @@ -991,9 +1054,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1015,12 +1078,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1028,9 +1092,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1041,9 +1105,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1055,15 +1119,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1075,15 +1139,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1095,6 +1159,12 @@ dependencies = [ ] [[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] name = "idna" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1107,9 +1177,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1117,30 +1187,23 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", -] - -[[package]] -name = "indoc" -version = "2.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", + "hashbrown 0.17.1", + "serde", + "serde_core", ] [[package]] name = "inotify" -version = "0.11.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "inotify-sys", "libc", ] @@ -1156,19 +1219,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" -dependencies = [ - "memchr", - "serde", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is-terminal" @@ -1207,25 +1260,85 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "f2025f20d7a4fa7785846e7b63d10a76d3f1cee98ee5cb79ea59703f95e42162" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] [[package]] name = "kqueue" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5" dependencies = [ "kqueue-sys", "libc", @@ -1233,11 +1346,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.13.0", "libc", ] @@ -1251,10 +1364,16 @@ dependencies = [ ] [[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] name = "libc" -version = "0.2.177" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libloading" @@ -1268,13 +1387,13 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libmpv2" -version = "1.8.0" +version = "1.9.0" dependencies = [ "crossbeam", "libmpv2-sys", @@ -1284,20 +1403,21 @@ dependencies = [ [[package]] name = "libmpv2-sys" -version = "1.8.0" +version = "1.9.0" dependencies = [ "bindgen", ] [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "libc", - "redox_syscall", + "plain", + "redox_syscall 0.8.1", ] [[package]] @@ -1313,9 +1433,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.23" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -1325,15 +1445,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -1346,9 +1466,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "md-5" @@ -1362,18 +1488,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "mime" @@ -1389,9 +1506,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "log", @@ -1400,23 +1517,6 @@ dependencies = [ ] [[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1432,7 +1532,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "inotify", "kqueue", "libc", @@ -1445,9 +1545,12 @@ dependencies = [ [[package]] name = "notify-types" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" +checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" +dependencies = [ + "bitflags 2.13.0", +] [[package]] name = "num-bigint-dig" @@ -1460,7 +1563,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.6", "smallvec", "zeroize", ] @@ -1497,9 +1600,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -1508,42 +1611,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" +name = "openssl-probe" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -1575,7 +1658,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -1640,15 +1723,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs1" @@ -1673,21 +1750,27 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -1723,44 +1806,41 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a6df7eab65fc7bee654a421404947e10a0f7085b6951bf2ea395f4659fb0cf" +checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12" dependencies = [ - "indoc", "libc", - "memoffset", "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", - "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77d387774f6f6eec64a004eac0ed525aab7fa1966d94b42f743797b3e395afb" +checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd13844a4242793e02df3e2ec093f540d948299a6a77ea9ce7afd8623f542be" +checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e" dependencies = [ "libc", "pyo3-build-config", @@ -1768,9 +1848,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf8f9f1108270b90d3676b8679586385430e5c0bb78bb5f043f95499c821a71" +checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1780,9 +1860,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a3b2274450ba5288bc9b8c1b69ff569d1d61189d4bff38f8d22e03d17f932b" +checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb" dependencies = [ "heck", "proc-macro2", @@ -1793,7 +1873,7 @@ dependencies = [ [[package]] name = "pyo3-pylogger" -version = "1.8.0" +version = "1.9.0" dependencies = [ "log", "phf", @@ -1801,10 +1881,66 @@ dependencies = [ ] [[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.4", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] name = "quote" -version = "1.0.42" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -1816,14 +1952,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -1833,7 +1985,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -1842,7 +2004,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", ] [[package]] @@ -1851,14 +2022,23 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", +] + +[[package]] +name = "redox_syscall" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" +dependencies = [ + "bitflags 2.13.0", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -1868,9 +2048,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -1879,15 +2059,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" -version = "0.12.24" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -1899,21 +2079,19 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", - "hyper-tls", "hyper-util", "js-sys", "log", "mime", - "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", + "rustls-platform-verifier", "sync_wrapper", "tokio", - "tokio-native-tls", + "tokio-rustls", "tower", "tower-http", "tower-service", @@ -1931,7 +2109,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -1939,9 +2117,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ "const-oid", "digest", @@ -1950,7 +2128,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "signature", "spki", "subtle", @@ -1959,17 +2137,26 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys", @@ -1978,10 +2165,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "aws-lc-rs", "once_cell", "rustls-pki-types", "rustls-webpki", @@ -1990,20 +2178,61 @@ dependencies = [ ] [[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ + "web-time", "zeroize", ] [[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2017,9 +2246,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -2032,9 +2261,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -2070,12 +2299,12 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", - "core-foundation", + "bitflags 2.13.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2083,15 +2312,21 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", ] [[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2123,22 +2358,22 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -2162,7 +2397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -2173,7 +2408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -2184,11 +2419,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -2199,20 +2441,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -2225,12 +2483,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2345,7 +2603,7 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags 2.13.0", "byteorder", "bytes", "crc", @@ -2366,7 +2624,7 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rand", + "rand 0.8.6", "rsa", "serde", "sha1", @@ -2387,7 +2645,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags 2.13.0", "byteorder", "crc", "dotenvy", @@ -2404,7 +2662,7 @@ dependencies = [ "md-5", "memchr", "once_cell", - "rand", + "rand 0.8.6", "serde", "serde_json", "sha2", @@ -2484,9 +2742,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.111" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -2515,12 +2773,12 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.10.0", - "core-foundation", + "bitflags 2.13.0", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2536,18 +2794,18 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2564,7 +2822,7 @@ dependencies = [ [[package]] name = "termsize" -version = "1.8.0" +version = "1.9.0" dependencies = [ "libc", "winapi", @@ -2572,18 +2830,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -2601,9 +2859,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -2611,9 +2869,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -2626,9 +2884,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -2642,9 +2900,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -2652,16 +2910,6 @@ dependencies = [ ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2673,9 +2921,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -2684,9 +2932,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -2698,9 +2946,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ "indexmap", "serde_core", @@ -2713,33 +2961,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -2752,20 +3000,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.7" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -2782,9 +3030,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -2805,9 +3053,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -2820,9 +3068,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-bidi" @@ -2832,9 +3080,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" @@ -2858,10 +3106,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] -name = "unindent" -version = "0.2.4" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" @@ -2871,14 +3119,15 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -2895,7 +3144,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uu_fmt" -version = "1.8.0" +version = "1.9.0" dependencies = [ "unicode-width", ] @@ -2945,11 +3194,20 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] @@ -2960,9 +3218,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "a254a4b10c19a76f09a27640e7ffbf9bc30bf67e16a3bf28aaefa4920fe81563" dependencies = [ "cfg-if", "once_cell", @@ -2973,22 +3231,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "54568702fabf5d4849ce2b90fadfa64168a097eaf4b351ce9df8b687a0086aaf" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "24a40fc75b0ec6f3746ceb10d36f53a93dcd68a93b11b6445983945d79eba0dc" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2996,9 +3251,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "908f34bd9b9ce3d4caf07b72dfab63d61504d156856c6bd3cd87fa350cf3985b" dependencies = [ "bumpalo", "proc-macro2", @@ -3009,24 +3264,77 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "7acbf7616c27b194bbb550bf77ed0c2c3e5b7fd1260a93082b95fb7f47959b92" dependencies = [ "unicode-ident", ] [[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.13.0", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0871acf327f283dc6da28a1696cdc64fb355ba9f935d052021fa77f35cce69" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + +[[package]] name = "whoami" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3370,21 +3678,109 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.13.0", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xdg" @@ -3400,9 +3796,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3411,9 +3807,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -3423,7 +3819,7 @@ dependencies = [ [[package]] name = "yt" -version = "1.8.0" +version = "1.9.0" dependencies = [ "anyhow", "blake3", @@ -3437,11 +3833,10 @@ dependencies = [ "log", "notify", "pretty_assertions", - "regex", "reqwest", "serde", "serde_json", - "shlex", + "shlex 2.0.1", "sqlx", "stderrlog", "tempfile", @@ -3457,7 +3852,7 @@ dependencies = [ [[package]] name = "yt_dlp" -version = "1.8.0" +version = "1.9.0" dependencies = [ "curl", "log", @@ -3471,18 +3866,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.30" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.30" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -3491,18 +3886,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -3518,9 +3913,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -3529,9 +3924,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -3540,11 +3935,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" @@ -21,7 +21,7 @@ members = [ [workspace.package] edition = "2024" -version = "1.8.0" +version = "1.9.0" rust-version = "1.85.0" authors = ["Benedikt Peetz <benedikt.peetz@b-peetz.de>"] repository = "https://git.vhack.eu/soispha/clients/yt" @@ -37,12 +37,12 @@ uu_fmt = { path = "./crates/fmt" } colors = { path = "./crates/colors" } # Shared -pyo3 = { version = "0.27.1", features = ["macros"], default-features = false } -log = { version = "0.4.28", features = ["kv"] } +pyo3 = { version = "0.28.3", features = ["macros"], default-features = false } +log = { version = "0.4.32", features = ["kv"] } serde = { version = "1.0.228", features = ["derive"] } -serde_json = "1.0.145" -url = { version = "2.5.7", features = ["serde"] } -tokio = { version = "1.48.0", features = [ +serde_json = "1.0.150" +url = { version = "2.5.8", features = ["serde"] } +tokio = { version = "1.52.3", features = [ "rt-multi-thread", "macros", "process", @@ -14,6 +14,24 @@ If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. - - - +## [v1.9.0](https://git.foss-syndicate.org/soispha/clients/yt/compare/6f0b086f7830f27a7d938bc03db0c73295d745e2..v1.9.0) - 2025-11-30 +#### Features +- (**yt/commands/subs**) Implement disabling subscriptions - ([6f0b086](https://git.foss-syndicate.org/soispha/clients/yt/commit/6f0b086f7830f27a7d938bc03db0c73295d745e2)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +#### Bug Fixes +- (**treewide**) Avoid using deprecated functions or patterns - ([8158bcf](https://git.foss-syndicate.org/soispha/clients/yt/commit/8158bcf6da8163fd35f26b59a08fc7f5a9abce11)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**yt/commands/download**) Fix typo - ([3f165f5](https://git.foss-syndicate.org/soispha/clients/yt/commit/3f165f5a118a097758942d534f2e32d6aa889981)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**yt/commands/download/progress_hook**) Show title, if already downloaded - ([52955b8](https://git.foss-syndicate.org/soispha/clients/yt/commit/52955b88a26b0dcd344e7619bdb5bef1082f1806)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**yt/commands/select/add**) Correct add behaviour - ([7855ca1](https://git.foss-syndicate.org/soispha/clients/yt/commit/7855ca1efa7d6c107c859ea05498f4d79eb8fe46)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**yt/commands/status**) Show active subscriptions number - ([2ab1e54](https://git.foss-syndicate.org/soispha/clients/yt/commit/2ab1e54e36f0b9caeb7a0258c75476d3b53b61fd)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +#### Build system +- (**devenv**) Include deno - ([dfe0173](https://git.foss-syndicate.org/soispha/clients/yt/commit/dfe017331b5f90db682ecedeb18817a2e68b0379)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**package**) Also include `deno` in the buildInputs - ([7ba761c](https://git.foss-syndicate.org/soispha/clients/yt/commit/7ba761c4af3a204837521535707025b79461c31b)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**package**) Use `ffmpeg-headless` instead of `ffmpeg` - ([9f82f36](https://git.foss-syndicate.org/soispha/clients/yt/commit/9f82f3691336f616379c00ea14e3b5b91bd44fc2)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**treewide**) Update - ([668bcef](https://git.foss-syndicate.org/soispha/clients/yt/commit/668bcef7684093859f0d8931f89cd015260d99ee)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) +- (**update.sh**) Also work, when the cwd directory changed - ([6d052bc](https://git.foss-syndicate.org/soispha/clients/yt/commit/6d052bc60730818881da4c54b7ec27dca1862fae)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) + +- - - + ## [v1.8.0](https://git.foss-syndicate.org/soispha/clients/yt/compare/4276f312926c0b166967066ca06887d42e362561..v1.8.0) - 2025-07-24 #### Bug Fixes - **(crates/yt)** Correct imports - ([ac99460](https://git.foss-syndicate.org/soispha/clients/yt/commit/ac99460ed65126d32160ac12641f211d9162db91)) - [@bpeetz](https://git.foss-syndicate.org/bpeetz) diff --git a/crates/libmpv2/libmpv2-sys/update.sh b/crates/libmpv2/libmpv2-sys/update.sh deleted file mode 100755 index c1a0215..0000000 --- a/crates/libmpv2/libmpv2-sys/update.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env sh - -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -cd "$(dirname "$0")" || exit 1 -[ "$1" = "upgrade" ] && cargo upgrade --incompatible -cargo update diff --git a/crates/libmpv2/update.sh b/crates/libmpv2/update.sh deleted file mode 100755 index e1669a9..0000000 --- a/crates/libmpv2/update.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -"$(dirname "$0")/libmpv2-sys/update.sh" "$@" diff --git a/crates/yt/Cargo.toml b/crates/yt/Cargo.toml index 6184eb7..91d9204 100644 --- a/crates/yt/Cargo.toml +++ b/crates/yt/Cargo.toml @@ -24,33 +24,32 @@ rust-version.workspace = true publish = false [dependencies] -anyhow = "1.0.100" -blake3 = { version = "1.8.2", features = ["serde"] } -chrono = { version = "0.4.42", features = ["now"] } +anyhow = "1.0.102" +blake3 = { version = "1.8.5", features = ["serde"] } +chrono = { version = "0.4.45", features = ["now"] } chrono-humanize = "0.2.3" -clap = { version = "4.5.53", features = ["derive"] } -clap_complete = { version = "4.5.61", features = ["unstable-dynamic"] } +clap = { version = "4.6.1", features = ["derive"] } +clap_complete = { version = "4.6.5", features = ["unstable-dynamic"] } colors.workspace = true -futures = "0.3.31" +futures = "0.3.32" libmpv2.workspace = true log.workspace = true notify = { version = "8.2.0", default-features = false } -regex = "1.12.2" serde.workspace = true serde_json.workspace = true -shlex = "1.3.0" +shlex = "2.0.1" sqlx = { version = "0.8.6", features = ["runtime-tokio", "sqlite"] } stderrlog = "0.6.0" -tempfile = "3.23.0" +tempfile = "3.27.0" termsize.workspace = true -tokio-util = { version = "0.7.17", features = ["rt"] } +tokio-util = { version = "0.7.18", features = ["rt"] } tokio.workspace = true -toml = "0.9.8" +toml = "1.1.2" url.workspace = true uu_fmt.workspace = true xdg = "3.0.0" yt_dlp.workspace = true -reqwest = "0.12.24" +reqwest = "0.13.4" [[bin]] name = "yt" diff --git a/crates/yt/src/ansi_escape_codes.rs b/crates/yt/src/ansi_escape_codes.rs index 28a8370..0348d89 100644 --- a/crates/yt/src/ansi_escape_codes.rs +++ b/crates/yt/src/ansi_escape_codes.rs @@ -8,22 +8,24 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +use std::io::Write; + // see: https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands const CSI: &str = "\x1b["; -pub(crate) fn erase_from_cursor_to_bottom() { - print!("{CSI}0J"); +pub(crate) fn erase_from_cursor_to_bottom<W: Write>(mut stream: W) { + write!(stream, "{CSI}0J").expect("the stream to accept writes"); } -pub(crate) fn cursor_up(number: usize) { +pub(crate) fn cursor_up<W: Write>(mut stream: W, number: usize) { // HACK(@bpeetz): The default is `1` and running this command with a // number of `0` results in it using the default (i.e., `1`) <2025-03-25> if number != 0 { - print!("{CSI}{number}A"); + write!(stream, "{CSI}{number}A").expect("the stream to accept writes"); } } -pub(crate) fn clear_whole_line() { - eprint!("{CSI}2K"); +pub(crate) fn clear_whole_line<W: Write>(mut stream: W) { + write!(stream, "{CSI}2K").expect("the stream to accept writes"); } -pub(crate) fn move_to_col(x: usize) { - eprint!("{CSI}{x}G"); +pub(crate) fn move_to_col<W: Write>(mut stream: W, x: usize) { + write!(stream, "{CSI}{x}G").expect("the stream to accept writes"); } diff --git a/crates/yt/src/cli.rs b/crates/yt/src/cli.rs index 9a24403..dbdcdd1 100644 --- a/crates/yt/src/cli.rs +++ b/crates/yt/src/cli.rs @@ -41,6 +41,11 @@ pub(crate) struct CliArgs { #[arg(long, short)] pub(crate) db_path: Option<PathBuf>, + /// Set the cookie file to be passed to `yt_dlp`. This overrides the default and the value from + /// the config file. + #[arg(long, short = 'P')] + pub(crate) cookies: Option<PathBuf>, + /// Set the path to the config.toml. /// This overrides the default. #[arg(long, short)] diff --git a/crates/yt/src/commands/download/implm/download/download_options.rs b/crates/yt/src/commands/download/implm/download/download_options.rs index 15fed7e..4174266 100644 --- a/crates/yt/src/commands/download/implm/download/download_options.rs +++ b/crates/yt/src/commands/download/implm/download/download_options.rs @@ -15,14 +15,15 @@ use yt_dlp::{YoutubeDL, options::YoutubeDLOptions}; use crate::app::App; -use super::progress_hook::wrapped_progress_hook; +use super::hooks::{wrapped_progress_hook, wrapped_post_processor_hook}; pub(crate) fn download_opts( app: &App, - subtitle_langs: Option<&String>, + subtitle_langs: Option<&str>, ) -> anyhow::Result<YoutubeDL> { - YoutubeDLOptions::new() + let base = YoutubeDLOptions::new() .with_progress_hook(wrapped_progress_hook) + .with_post_processor_hook(wrapped_post_processor_hook) .set("extract_flat", "in_playlist") .set( "extractor_args", @@ -35,7 +36,6 @@ pub(crate) fn download_opts( } }, ) - //.set("cookiesfrombrowser", json! {("firefox", "me.google", None::<String>, "youtube_dlp")}) .set("prefer_free_formats", true) .set("ffmpeg_location", env!("FFMPEG_LOCATION")) .set("format", "bestvideo[height<=?1080]+bestaudio/best") @@ -110,12 +110,18 @@ pub(crate) fn download_opts( "subtitleslangs", Value::Array( subtitle_langs - .map_or("", String::as_str) + .unwrap_or("") .split(',') .map(|val| Value::String(val.to_owned())) .collect::<Vec<_>>(), ), - ) - .build() - .context("Failed to instanciate download yt_dlp") + ); + + if let Some(cookies) = &app.config.global.cookies { + base.set("cookies", cookies.to_str()) + } else { + base + } + .build() + .context("Failed to instanciate download yt_dlp") } diff --git a/crates/yt/src/commands/download/implm/download/progress_hook.rs b/crates/yt/src/commands/download/implm/download/hooks.rs index a414d4a..de52b98 100644 --- a/crates/yt/src/commands/download/implm/download/progress_hook.rs +++ b/crates/yt/src/commands/download/implm/download/hooks.rs @@ -12,15 +12,21 @@ use std::{ collections::HashSet, io::{Write, stderr}, process, - sync::{Mutex, atomic::Ordering}, + sync::{ + Mutex, OnceLock, + atomic::{AtomicUsize, Ordering}, + mpsc::{self, Sender}, + }, + thread, + time::Duration, }; use colors::{Colorize, IntoCanvas}; use log::{Level, log_enabled}; -use yt_dlp::{json_cast, json_get, wrap_progress_hook}; +use yt_dlp::{json_cast, json_get, json_try_get, wrap_post_processor_hook, wrap_progress_hook}; use crate::{ - ansi_escape_codes::{clear_whole_line, move_to_col}, + ansi_escape_codes::{clear_whole_line, cursor_up, erase_from_cursor_to_bottom, move_to_col}, config::SHOULD_DISPLAY_COLOR, select::duration::MaybeDuration, shared::bytes::Bytes, @@ -50,10 +56,31 @@ fn format_speed(speed: f64) -> String { let bytes = Bytes::new(speed.floor() as u64); format!("{bytes}/s") } +fn get_title(info_dict: &serde_json::Map<String, serde_json::Value>) -> String { + if let Some(ext) = json_try_get!(info_dict, "ext", as_str) { + match ext { + "vtt" => { + format!( + "Subtitles ({})", + json_get_default!(info_dict, "name", as_str, "<No Subtitle Language>") + ) + } + "webm" | "mp4" | "mp3" | "m4a" => { + json_get_default!(info_dict, "title", as_str, "<No title>").to_owned() + } + other => panic!("The extension '{other}' is not yet implemented"), + } + } else { + json_get_default!(info_dict, "title", as_str, "<No title>").to_owned() + } +} /// # Panics /// If expectations fail. -#[allow(clippy::needless_pass_by_value)] +#[expect( + clippy::needless_pass_by_value, + reason = "We need to conform to the expected function signature" +)] pub(crate) fn progress_hook( input: serde_json::Map<String, serde_json::Value>, ) -> Result<(), std::io::Error> { @@ -65,21 +92,6 @@ pub(crate) fn progress_hook( let info_dict = json_get!(input, "info_dict", as_object); - let get_title = || -> String { - match json_get!(info_dict, "ext", as_str) { - "vtt" => { - format!( - "Subtitles ({})", - json_get_default!(info_dict, "name", as_str, "<No Subtitle Language>") - ) - } - "webm" | "mp4" | "mp3" | "m4a" => { - json_get_default!(info_dict, "title", as_str, "<No title>").to_owned() - } - other => panic!("The extension '{other}' is not yet implemented"), - } - }; - match json_get!(input, "status", as_str) { "downloading" => { let elapsed = json_get_default!(input, "elapsed", as_f64, 0.0); @@ -127,12 +139,12 @@ pub(crate) fn progress_hook( } }; - clear_whole_line(); - move_to_col(1); + clear_whole_line(stderr()); + move_to_col(stderr(), 1); let should_use_color = SHOULD_DISPLAY_COLOR.load(Ordering::Relaxed); - let title = get_title(); + let title = get_title(info_dict); eprint!( "{} [{}/{} at {}] -> [{} of {}{} {}] ", @@ -175,7 +187,7 @@ pub(crate) fn progress_hook( } "finished" => { let should_use_color = SHOULD_DISPLAY_COLOR.load(Ordering::Relaxed); - let title = get_title(); + let title = get_title(info_dict); let has_already_been_printed = { let titles = TITLES.lock().expect("The lock should work"); @@ -198,7 +210,7 @@ pub(crate) fn progress_hook( "error" => { // TODO: This should probably return an Err. But I'm not so sure where the error would // bubble up to (i.e., who would catch it) <2025-01-21> - eprintln!("-> Error while downloading: {}", get_title()); + eprintln!("-> Error while downloading: {}", get_title(info_dict)); process::exit(1); } other => unreachable!("'{other}' should not be a valid state!"), @@ -207,4 +219,141 @@ pub(crate) fn progress_hook( Ok(()) } +// postprocessor_hooks: A list of functions that get called on postprocessing +// progress, with a dictionary with the entries +// * status: One of "started", "processing", or "finished". +// Check this first and ignore unknown values. +// * postprocessor: Name of the postprocessor +// * info_dict: The extracted info_dict +// +// Progress hooks are guaranteed to be called at least twice +// (with status "started" and "finished") if the processing is successful. +#[expect( + clippy::needless_pass_by_value, + clippy::unnecessary_wraps, + reason = "The macro expects this function signature" +)] +pub(crate) fn post_processor_hook( + input: serde_json::Map<String, serde_json::Value>, +) -> Result<(), std::io::Error> { + // Only add the handler, if the log-level is higher than Debug (this avoids covering debug + // messages). + if log_enabled!(Level::Debug) { + return Ok(()); + } + + let info_dict = json_get!(input, "info_dict", as_object); + + match json_get!(input, "status", as_str) { + "started" => { + // Normally `yt_dlp` just gives us a `started` and a `finished` message, so we show all + // the post_processors that have currently been recorded as `started` and not yet as + // `finished`. + let post_processor = json_get!(input, "postprocessor", as_str); + maybe_setup_post_processor_progress(ProgressChange::Started( + post_processor.to_string(), + )); + } + "processing" => { + let post_processor = json_get!(input, "postprocessor", as_str); + let title = get_title(info_dict); + + eprintln!("Processesing actually triggered, `{post_processor}` for `{title}`",); + } + "finished" => { + let post_processor = json_get!(input, "postprocessor", as_str); + maybe_setup_post_processor_progress(ProgressChange::Finished( + post_processor.to_string(), + )); + + // let should_use_color = SHOULD_DISPLAY_COLOR.load(Ordering::Relaxed); + // let title = get_title(info_dict); + // + // eprintln!( + // "{} ({}) finished.", + // title.bold().blue().render(should_use_color), + // post_processor.bold().green().render(should_use_color), + // ); + } + other => unreachable!("'{other}' should not be a valid state!"), + } + + Ok(()) +} + +enum ProgressChange { + Started(String), + Finished(String), +} + +fn maybe_setup_post_processor_progress(pc: ProgressChange) { + fn new_state_id() -> usize { + static COUNTER: AtomicUsize = AtomicUsize::new(0); + COUNTER.fetch_add(1, Ordering::Relaxed) + } + static TX: OnceLock<Sender<ProgressChange>> = const { OnceLock::new() }; + + let should_use_color = SHOULD_DISPLAY_COLOR.load(Ordering::Relaxed); + + let tx = TX.get_or_init(|| { + let (tx, rx) = mpsc::channel(); + thread::spawn(move || { + fn process_new_data(data: &mut HashSet<String>, new_data: ProgressChange) { + match new_data { + ProgressChange::Started(name) => { + data.insert(name); + } + ProgressChange::Finished(name) => { + data.remove(&name); + } + } + } + + let mut data = HashSet::new(); + + 'main: loop { + let previous_length = data.len(); + + match rx.recv_timeout(Duration::from_millis(100)) { + Ok(new_data) => process_new_data(&mut data, new_data), + Err(err) => match err { + mpsc::RecvTimeoutError::Timeout => (), + mpsc::RecvTimeoutError::Disconnected => break 'main, + }, + } + + // If we received multiple things at once, process them all at once. + while let Ok(new_data) = rx.try_recv() { + process_new_data(&mut data, new_data); + } + + let spinner = match new_state_id() % 4 { + 0 => '|', + 1 => '/', + 2 => '-', + 3 => '\\', + _ => unreachable!("The `mod` operation does not permit these numbers"), + }; + + cursor_up(stderr(), previous_length); + erase_from_cursor_to_bottom(stderr()); + for post_processor in &data { + clear_whole_line(stderr()); + move_to_col(stderr(), 1); + + eprintln!( + "[{spinner}] {} ", + post_processor.blue().bold().render(should_use_color) + ); + } + } + }); + tx + }); + + tx.send(pc) + .expect("The recieving end should not be dropped before we drop the tx"); +} + wrap_progress_hook!(progress_hook, wrapped_progress_hook); +wrap_post_processor_hook!(post_processor_hook, wrapped_post_processor_hook); diff --git a/crates/yt/src/commands/download/implm/download/mod.rs b/crates/yt/src/commands/download/implm/download/mod.rs index ab9de80..39f7960 100644 --- a/crates/yt/src/commands/download/implm/download/mod.rs +++ b/crates/yt/src/commands/download/implm/download/mod.rs @@ -29,7 +29,7 @@ use yt_dlp::YoutubeDL; #[allow(clippy::module_name_repetitions)] pub(crate) mod download_options; -pub(crate) mod progress_hook; +pub(crate) mod hooks; #[derive(Debug)] #[allow(clippy::module_name_repetitions)] @@ -44,13 +44,13 @@ impl CurrentDownload { let extractor_hash = video.extractor_hash; debug!("Download started: {}", &video.title); - let yt_dlp = Arc::new(download_opts(app, video.subtitle_langs.as_ref())?); + let yt_dlp = Arc::new(download_opts(app, video.subtitle_langs.as_deref())?); let local_yt_dlp = Arc::clone(&yt_dlp); let task_handle = tokio::task::spawn_blocking(move || { let mut result = local_yt_dlp - .download(&[video.url.clone()]) + .download(std::slice::from_ref(&video.url)) .with_context(|| format!("Failed to download video: '{}'", video.title))?; assert_eq!(result.len(), 1); diff --git a/crates/yt/src/commands/implm.rs b/crates/yt/src/commands/implm.rs index 7c60c6a..d8ef146 100644 --- a/crates/yt/src/commands/implm.rs +++ b/crates/yt/src/commands/implm.rs @@ -27,6 +27,7 @@ impl Command { } Command::Show { cmd } => cmd.implm(&app).await?, Command::Status { cmd } => cmd.implm(&app).await?, + Command::Stats { cmd } => cmd.implm(&app).await?, Command::Subscriptions { cmd } => cmd.implm(&app).await?, Command::Update { cmd } => cmd.implm(&app).await?, Command::Videos { cmd } => cmd.implm(&app).await?, diff --git a/crates/yt/src/commands/mod.rs b/crates/yt/src/commands/mod.rs index 431acef..5eb1fad 100644 --- a/crates/yt/src/commands/mod.rs +++ b/crates/yt/src/commands/mod.rs @@ -19,11 +19,12 @@ use crate::{ commands::{ cache::CacheCommand, config::ConfigCommand, database::DatabaseCommand, download::DownloadCommand, playlist::PlaylistCommand, select::SelectCommand, - show::ShowCommand, status::StatusCommand, subscriptions::SubscriptionCommand, - update::UpdateCommand, videos::VideosCommand, watch::WatchCommand, + show::ShowCommand, stats::StatsCommand, status::StatusCommand, + subscriptions::SubscriptionCommand, update::UpdateCommand, videos::VideosCommand, + watch::WatchCommand, }, config::Config, - storage::db::subscription::Subscriptions, + storage::db::subscription::{Subscription, Subscriptions}, }; pub(super) mod implm; @@ -35,6 +36,7 @@ mod download; mod playlist; mod select; mod show; +mod stats; mod status; mod subscriptions; mod update; @@ -93,6 +95,12 @@ pub(super) enum Command { cmd: StatusCommand, }, + /// Show general stats about your `yt` usage + Stats { + #[command(flatten)] + cmd: StatsCommand, + }, + /// Manipulate subscription #[command(visible_alias = "subs")] Subscriptions { @@ -126,15 +134,24 @@ impl Default for Command { } } } +fn complete_subscription_active(current: &OsStr) -> Vec<CompletionCandidate> { + complete_subscription_condition(current, |sub| sub.is_active) +} +fn complete_subscription_inactive(current: &OsStr) -> Vec<CompletionCandidate> { + complete_subscription_condition(current, |sub| !sub.is_active) +} -fn complete_subscription(current: &OsStr) -> Vec<CompletionCandidate> { - let mut output = vec![]; +fn complete_subscription_condition( + current: &OsStr, + condition: fn(&Subscription) -> bool, +) -> Vec<CompletionCandidate> { + let output = vec![]; let Some(current_prog) = current.to_str().map(ToOwned::to_owned) else { return output; }; - let Ok(config) = Config::from_config_file(None, None, None) else { + let Ok(config) = Config::from_config_file(None, None, None, None) else { return output; }; @@ -151,14 +168,21 @@ fn complete_subscription(current: &OsStr) -> Vec<CompletionCandidate> { return output; }; - for sub in all.0.into_keys() { - if sub.starts_with(¤t_prog) { - output.push(CompletionCandidate::new(sub)); + let mut pre_output = vec![]; + for (sub_name, sub) in all.0 { + if sub_name.starts_with(¤t_prog) && condition(&sub) { + pre_output.push((sub_name.clone(), CompletionCandidate::new(sub_name))); } } - output + pre_output.sort_by_key(|(name, _)| name.clone()); + + pre_output.into_iter().map(|(_, comp)| comp).collect() }); handle.join().unwrap_or_default() } + +fn complete_subscription(current: &OsStr) -> Vec<CompletionCandidate> { + complete_subscription_condition(current, |_| true) +} diff --git a/crates/yt/src/commands/playlist/implm.rs b/crates/yt/src/commands/playlist/implm.rs index 603184b..adb75da 100644 --- a/crates/yt/src/commands/playlist/implm.rs +++ b/crates/yt/src/commands/playlist/implm.rs @@ -8,7 +8,7 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{fmt::Write, path::Path}; +use std::{fmt::Write, io::stdout, path::Path}; use crate::{ ansi_escape_codes, @@ -78,8 +78,8 @@ impl PlaylistCommand { .await?; // Delete the previous output - ansi_escape_codes::cursor_up(previous_output_length); - ansi_escape_codes::erase_from_cursor_to_bottom(); + ansi_escape_codes::cursor_up(stdout(), previous_output_length); + ansi_escape_codes::erase_from_cursor_to_bottom(stdout()); previous_output_length = output.chars().filter(|ch| *ch == '\n').count(); diff --git a/crates/yt/src/commands/select/implm/fs_generators/mod.rs b/crates/yt/src/commands/select/implm/fs_generators/mod.rs index 10da032..a0f9098 100644 --- a/crates/yt/src/commands/select/implm/fs_generators/mod.rs +++ b/crates/yt/src/commands/select/implm/fs_generators/mod.rs @@ -24,7 +24,7 @@ use crate::{ commands::{ Command, select::{ - SelectCommand, SelectSplitSortKey, SelectSplitSortMode, + SelectCommand, SelectFileSortKey, SelectSplitSortKey, SortMode, implm::standalone::{self, handle_select_cmd}, }, }, @@ -48,7 +48,7 @@ pub(crate) async fn select_split( app: &App, done: bool, sort_key: SelectSplitSortKey, - sort_mode: SelectSplitSortMode, + sort_mode: SortMode, ) -> Result<()> { let temp_dir = tempfile::Builder::new() .prefix("yt_video_select-") @@ -81,7 +81,7 @@ pub(crate) async fn select_split( match sort_key { SelectSplitSortKey::Publisher => { - // PERFORMANCE: The clone here should not be neeed. <2025-06-15> + // PERFORMANCE: The clone here should not be needed. <2025-06-15> temp_vec.sort_by_key(|(name, _): &(String, Vec<Video>)| name.to_owned()); } SelectSplitSortKey::Videos => { @@ -90,10 +90,10 @@ pub(crate) async fn select_split( } match sort_mode { - SelectSplitSortMode::Asc => { + SortMode::Asc => { // Std's default mode is ascending. } - SelectSplitSortMode::Desc => { + SortMode::Desc => { temp_vec.reverse(); } } @@ -171,7 +171,13 @@ pub(crate) async fn select_split( Ok(()) } -pub(crate) async fn select_file(app: &App, done: bool, use_last_selection: bool) -> Result<()> { +pub(crate) async fn select_file( + app: &App, + done: bool, + sort_key: SelectFileSortKey, + sort_mode: SortMode, + use_last_selection: bool, +) -> Result<()> { let temp_file = tempfile::Builder::new() .prefix("yt_video_select-") .suffix(".yts") @@ -182,7 +188,34 @@ pub(crate) async fn select_file(app: &App, done: bool, use_last_selection: bool) if use_last_selection { fs::copy(&app.config.paths.last_selection_path, &temp_file)?; } else { - let matching_videos = get_videos(app, done).await?; + let mut matching_videos = get_videos(app, done).await?; + + match sort_key { + SelectFileSortKey::Priority => { + // The default sort is by priority + } + SelectFileSortKey::ReleaseDate => { + matching_videos.sort_by_key(|video| video.publish_date.unwrap_or_default()); + } + SelectFileSortKey::Author => matching_videos.sort_by_key(|video| { + video + .parent_subscription_name + .as_ref() + .map(|s| s.as_str()) + .unwrap_or("") + .to_owned() + }), + SelectFileSortKey::Title => matching_videos.sort_by_key(|video| video.title.clone()), + } + + match sort_mode { + SortMode::Asc => { + // The default is ascending + } + SortMode::Desc => { + matching_videos.reverse(); + } + } write_videos_to_file(app, temp_file.as_file(), &matching_videos).await?; } diff --git a/crates/yt/src/commands/select/implm/mod.rs b/crates/yt/src/commands/select/implm/mod.rs index f39c77f..5aaf4a1 100644 --- a/crates/yt/src/commands/select/implm/mod.rs +++ b/crates/yt/src/commands/select/implm/mod.rs @@ -21,15 +21,29 @@ impl SelectCommand { SelectCommand::File { done, use_last_selection, - } => Box::pin(fs_generators::select_file(app, done, use_last_selection)).await?, + sort_mode, + sort_key, + } => { + Box::pin(fs_generators::select_file( + app, + done, + sort_key, + sort_mode, + use_last_selection, + )) + .await? + } + SelectCommand::Split { done, sort_key, sort_mode, } => Box::pin(fs_generators::select_split(app, done, sort_key, sort_mode)).await?, + SelectCommand::Add { urls, start, stop } => { Box::pin(standalone::add::add(app, urls, start, stop)).await?; } + other => { let shared = other .clone() diff --git a/crates/yt/src/commands/select/implm/standalone/mod.rs b/crates/yt/src/commands/select/implm/standalone/mod.rs index 9512e32..dfabc2b 100644 --- a/crates/yt/src/commands/select/implm/standalone/mod.rs +++ b/crates/yt/src/commands/select/implm/standalone/mod.rs @@ -108,8 +108,8 @@ async fn handle_status_change( } if !is_single { - ansi_escape_codes::clear_whole_line(); - ansi_escape_codes::move_to_col(1); + ansi_escape_codes::clear_whole_line(stderr()); + ansi_escape_codes::move_to_col(stderr(), 1); } eprint!("{}", &video.to_line_display(app, None).await?); diff --git a/crates/yt/src/commands/select/mod.rs b/crates/yt/src/commands/select/mod.rs index db69238..085c244 100644 --- a/crates/yt/src/commands/select/mod.rs +++ b/crates/yt/src/commands/select/mod.rs @@ -32,6 +32,14 @@ pub(super) enum SelectCommand { #[arg(long, short)] done: bool, + /// Which value to use to sort videos by + #[arg(long, short = 'k', default_value_t)] + sort_key: SelectFileSortKey, + + /// Which mode to use for sorting. + #[arg(long, short = 'm', default_value_t)] + sort_mode: SortMode, + /// Use the last selection file (useful if you've spend time on it and want to get it again) #[arg(long, short, conflicts_with = "done")] use_last_selection: bool, @@ -49,7 +57,7 @@ pub(super) enum SelectCommand { /// Which mode to use for sorting. #[arg(default_value_t)] - sort_mode: SelectSplitSortMode, + sort_mode: SortMode, }, /// Add a video to the database @@ -110,6 +118,8 @@ impl Default for SelectCommand { Self::File { done: false, use_last_selection: false, + sort_mode: SortMode::default(), + sort_key: SelectFileSortKey::default(), } } } @@ -211,7 +221,7 @@ impl Display for SelectSplitSortKey { } #[derive(Default, ValueEnum, Clone, Copy, Debug)] -enum SelectSplitSortMode { +enum SortMode { /// Sort in ascending order (small -> big) #[default] Asc, @@ -220,11 +230,38 @@ enum SelectSplitSortMode { Desc, } -impl Display for SelectSplitSortMode { +impl Display for SortMode { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + SortMode::Asc => f.write_str("asc"), + SortMode::Desc => f.write_str("desc"), + } + } +} + +#[derive(Default, ValueEnum, Clone, Copy, Debug)] +enum SelectFileSortKey { + /// Sort by the priority value, given to a video + #[default] + Priority, + + /// Sort by a videos release date + ReleaseDate, + + /// Sort by the videos author + Author, + + /// Sort by the videos title + Title, +} + +impl Display for SelectFileSortKey { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - SelectSplitSortMode::Asc => f.write_str("asc"), - SelectSplitSortMode::Desc => f.write_str("desc"), + SelectFileSortKey::Priority => f.write_str("priority"), + SelectFileSortKey::ReleaseDate => f.write_str("release_date"), + SelectFileSortKey::Author => f.write_str("author"), + SelectFileSortKey::Title => f.write_str("title"), } } } diff --git a/crates/yt/src/commands/stats/implm.rs b/crates/yt/src/commands/stats/implm.rs new file mode 100644 index 0000000..3fc9afe --- /dev/null +++ b/crates/yt/src/commands/stats/implm.rs @@ -0,0 +1,48 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +use crate::{ + app::App, + commands::StatsCommand, + storage::db::{insert::video, txn_log::TxnLog}, +}; + +use anyhow::Result; + +macro_rules! sort_by_operation { + ($opts:expr, $operation:path) => { + { + let mut new = Vec::with_capacity($opts.inner().len()); + + for (ts, op) in $opts.inner() { + if matches!(op, $operation { .. }) { + new.push((ts, op)); + } + } + + new + } + } +} + +impl StatsCommand { + pub(in crate::commands) async fn implm(self, app: &App) -> Result<()> { + let ops = TxnLog::<video::Operation>::get(app).await?; + + let only_add = sort_by_operation!(ops, video::Operation::Add); + + eprintln!("Number of operations: {}.", ops.inner().len()); + eprintln!("Number of added videos: {}.", only_add.len()); + + // TODO(@bpeetz): Also show watch-time over time, and move other things from `yt status` here. <2026-05-26> + + Ok(()) + } +} diff --git a/crates/yt/src/commands/stats/mod.rs b/crates/yt/src/commands/stats/mod.rs new file mode 100644 index 0000000..bd1eb9d --- /dev/null +++ b/crates/yt/src/commands/stats/mod.rs @@ -0,0 +1,16 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +use clap::Parser; + +mod implm; + +#[derive(Parser, Debug)] +pub(super) struct StatsCommand {} diff --git a/crates/yt/src/commands/status/implm.rs b/crates/yt/src/commands/status/implm.rs index 5832fde..2177012 100644 --- a/crates/yt/src/commands/status/implm.rs +++ b/crates/yt/src/commands/status/implm.rs @@ -130,7 +130,7 @@ impl StatusCommand { "{dropped_videos_len}", dropped_videos_len.to_string().as_str(), ) - .replace("{watchtime_status}", watchtime_status.to_string().as_str()) + .replace("{watchtime_status}", watchtime_status.as_str()) .replace( "{subscriptions_len}", subscriptions_len.to_string().as_str(), diff --git a/crates/yt/src/commands/subscriptions/implm.rs b/crates/yt/src/commands/subscriptions/implm.rs index 1e2e545..a4d9d6d 100644 --- a/crates/yt/src/commands/subscriptions/implm.rs +++ b/crates/yt/src/commands/subscriptions/implm.rs @@ -12,7 +12,7 @@ use std::str::FromStr; use crate::{ app::App, - commands::subscriptions::{SubscriptionCommand, SubscriptionStatus}, + commands::subscriptions::SubscriptionCommand, storage::db::{ insert::{Operations, subscription::Operation}, subscription::{Subscription, Subscriptions, check_url}, @@ -55,21 +55,22 @@ impl SubscriptionCommand { .await .with_context(|| format!("Failed to unsubscribe from {name:?}"))?; } - SubscriptionCommand::SetStatus { name, new_status } => { + SubscriptionCommand::SetStatus { new_status } => { let mut present_subscriptions = Subscriptions::get(app).await?; let mut ops = Operations::new("Subscribe: Set Status"); + + let (new_status, name) = match new_status { + super::NewStatus::Active { name } => (true, name), + super::NewStatus::Inactive { name } => (false, name), + }; + if let Some(subscription) = present_subscriptions.0.remove(&name) { - subscription.set_is_active( - match new_status { - SubscriptionStatus::Active => true, - SubscriptionStatus::Inactive => false, - }, - &mut ops, - ); + subscription.set_is_active(new_status, &mut ops); } else { bail!("Couldn't find subscription: '{}'", &name); } + ops.commit(app) .await .with_context(|| format!("Failed to change status of {name:?}"))?; diff --git a/crates/yt/src/commands/subscriptions/mod.rs b/crates/yt/src/commands/subscriptions/mod.rs index 6a16a9a..2ffc309 100644 --- a/crates/yt/src/commands/subscriptions/mod.rs +++ b/crates/yt/src/commands/subscriptions/mod.rs @@ -10,11 +10,13 @@ use std::path::PathBuf; -use clap::{Subcommand, ValueEnum}; +use clap::Subcommand; use clap_complete::ArgValueCompleter; use url::Url; -use crate::commands::complete_subscription; +use crate::commands::{ + complete_subscription, complete_subscription_active, complete_subscription_inactive, +}; mod implm; @@ -45,12 +47,9 @@ pub(super) enum SubscriptionCommand { /// /// An active subscription will be updated in `yt update`, while an inactive one will not. SetStatus { - /// The human readable name of the subscription - #[arg(add = ArgValueCompleter::new(complete_subscription))] - name: String, - /// What should this subscription be considered now? - new_status: SubscriptionStatus, + #[command(subcommand)] + new_status: NewStatus, }, /// Import a bunch of URLs as subscriptions. @@ -77,8 +76,16 @@ pub(super) enum SubscriptionCommand { }, } -#[derive(ValueEnum, Debug, Clone, Copy)] -pub(in crate::commands) enum SubscriptionStatus { - Active, - Inactive, +#[derive(Subcommand, Debug, Clone)] +pub(in crate::commands) enum NewStatus { + Active { + /// The human readable name of the subscription + #[arg(add = ArgValueCompleter::new(complete_subscription_inactive))] + name: String, + }, + Inactive { + /// The human readable name of the subscription + #[arg(add = ArgValueCompleter::new(complete_subscription_active))] + name: String, + }, } diff --git a/crates/yt/src/commands/update/implm/mod.rs b/crates/yt/src/commands/update/implm/mod.rs index 10626ac..b3064c1 100644 --- a/crates/yt/src/commands/update/implm/mod.rs +++ b/crates/yt/src/commands/update/implm/mod.rs @@ -11,13 +11,18 @@ use crate::{ app::App, commands::update::{UpdateCommand, implm::updater::Updater}, + select::duration::MaybeDuration, storage::db::{ extractor_hash::ExtractorHash, subscription::{Subscription, Subscriptions}, + video::{TimeStamp, Video}, }, }; use anyhow::{Result, bail}; +use chrono::TimeDelta; +use colors::{Colorize, IntoCanvas}; +use log::info; mod updater; @@ -26,6 +31,7 @@ impl UpdateCommand { let UpdateCommand { max_backlog, subscriptions: subscription_names_to_update, + force, } = self; let mut all_subs = Subscriptions::get(app).await?.remove_inactive(); @@ -42,20 +48,89 @@ impl UpdateCommand { Ok(val) } else { bail!( - "Your specified subscription to update '{}' is not a subscription!", - sub + "Your specified subscription to update '{sub}' is not a subscription!", ) } }) .collect::<Result<_>>()? }; + let real_subs = if force { + subs + } else { + // We only update these subscriptions if their last videos has been uploaded for longer than + // the average time between uploads. + + let mut real_subs = vec![]; + for sub in subs { + let mut videos: Vec<TimeStamp> = Video::from_subscription(&sub, app) + .await? + .into_iter() + .filter_map(|v| v.publish_date) + .collect(); + + if videos.is_empty() { + real_subs.push(sub); + break; + } + + videos.sort(); + + let average_time_between_videos: TimeDelta = { + let mut videos = videos.iter().copied(); + let mut last = videos.next().expect("we removed the empty video case"); + + let mut deltas = vec![]; + for next in videos { + deltas.push(next - last); + last = next; + } + + let sum: TimeDelta = deltas.iter().sum(); + + sum / deltas.len() as i32 + }; + + let last_video = videos.last().expect("to exist"); + + if average_time_between_videos <= (TimeStamp::from_now() - *last_video) { + real_subs.push(sub); + } else { + info!( + "Not adding '{}', as the average time between videos ({:#}) is longer than the last upload ({} {} ago) (use --force to override)", + sub.name.blue().render(app.config.global.display_colors), + MaybeDuration::from_std( + average_time_between_videos + .to_std() + .expect("Should be strictly positive") + ) + .green() + .bold() + .render(app.config.global.display_colors), + last_video + .magenta() + .render(app.config.global.display_colors), + MaybeDuration::from_std( + (TimeStamp::from_now() - *last_video) + .to_std() + .expect("Should be strictly positive") + ) + .green() + .bold() + .render(app.config.global.display_colors), + ); + } + } + + real_subs + }; + // We can get away with not having to re-fetch the hashes every time, as the returned video // should not contain duplicates. let hashes = ExtractorHash::get_all(app).await?; let updater = Updater::new(max_backlog, app.config.update.pool_size, hashes); - updater.update(app, subs).await?; + updater.update(app, real_subs).await?; Ok(()) } diff --git a/crates/yt/src/commands/update/implm/updater.rs b/crates/yt/src/commands/update/implm/updater.rs index 2b96bf2..d6fcbd0 100644 --- a/crates/yt/src/commands/update/implm/updater.rs +++ b/crates/yt/src/commands/update/implm/updater.rs @@ -8,7 +8,10 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{ + io, + sync::atomic::{AtomicUsize, Ordering}, +}; use anyhow::{Context, Result}; use futures::{StreamExt, future::join_all, stream}; @@ -87,14 +90,14 @@ impl Updater { .spawn_pinned(move || { async move { if !log_enabled!(Level::Debug) { - ansi_escape_codes::clear_whole_line(); - ansi_escape_codes::move_to_col(1); + ansi_escape_codes::clear_whole_line(io::stderr()); + ansi_escape_codes::move_to_col(io::stderr(), 1); eprint!( "({}/{total_number}) Checking playlist {}...", REACHED_NUMBER.fetch_add(1, Ordering::Relaxed), sub.name ); - ansi_escape_codes::move_to_col(1); + ansi_escape_codes::move_to_col(io::stderr(), 1); stderr().flush().await?; } diff --git a/crates/yt/src/commands/update/mod.rs b/crates/yt/src/commands/update/mod.rs index cb29148..f181626 100644 --- a/crates/yt/src/commands/update/mod.rs +++ b/crates/yt/src/commands/update/mod.rs @@ -21,6 +21,10 @@ pub(super) struct UpdateCommand { #[arg(short, long)] max_backlog: Option<usize>, + /// Update all specified subscriptions, regardless of average time between uploads + #[arg(short, long)] + force: bool, + /// The subscriptions to update #[arg(add = ArgValueCompleter::new(complete_subscription))] subscriptions: Vec<String>, diff --git a/crates/yt/src/config/mod.rs b/crates/yt/src/config/mod.rs index 05bb4cf..6e596de 100644 --- a/crates/yt/src/config/mod.rs +++ b/crates/yt/src/config/mod.rs @@ -48,7 +48,8 @@ mk_config! { struct Config { global: GlobalConfig = { /// Whether to display colors. - display_colors: bool where display_color: Option<bool> =! {|config_value: Option<bool>| + display_colors: bool where display_color: Option<bool> =! { + |config_value: Option<bool>| Ok::<_, anyhow::Error>( display_color .unwrap_or( @@ -57,6 +58,16 @@ mk_config! { ) ) } => set_static_should_display_color, + + /// The cookie file to pass to `yt_dlp`. + cookies: Option<PathBuf> where cookies_path: Option<PathBuf> =! { + |config_value: Option<Option<PathBuf>>| + if let Some(co) = cookies_path { + Ok::<_, anyhow::Error>(Some(co)) + } else { + Ok(config_value.unwrap_or(None)) + } + }, }, select: SelectConfig = { /// The playback speed to use, when it is not overridden. @@ -111,8 +122,13 @@ mk_config! { mpv_ipc_socket_path: PathBuf =? get_runtime_path("mpv.ipc.socket") => ensure_parent_dir, /// Path to the video database. - database_path: PathBuf where db_path: Option<PathBuf> =! {|config_value: Option<PathBuf>| { - db_path.map_or_else(|| config_value.map_or_else(|| get_data_path("videos.sqlite"), Ok), Ok) + database_path: PathBuf where db_path: Option<PathBuf> =! { + |config_value: Option<PathBuf>| { + db_path + .map_or_else( + || config_value.map_or_else(|| get_data_path("videos.sqlite"), Ok), + Ok + ) }} => ensure_parent_dir, /// Where to store the selection file before applying it. diff --git a/crates/yt/src/main.rs b/crates/yt/src/main.rs index 705e642..50e4a09 100644 --- a/crates/yt/src/main.rs +++ b/crates/yt/src/main.rs @@ -66,7 +66,9 @@ async fn main() -> Result<()> { } }); - let config = Config::from_config_file(args.config_path, args.color, args.db_path)?; + let config = + Config::from_config_file(args.config_path, args.color, args.cookies, args.db_path)?; + if args.version { version::show(&config).await?; return Ok(()); diff --git a/crates/yt/src/storage/db/get/txn_log.rs b/crates/yt/src/storage/db/get/txn_log.rs index 1a6df2c..8e3e950 100644 --- a/crates/yt/src/storage/db/get/txn_log.rs +++ b/crates/yt/src/storage/db/get/txn_log.rs @@ -23,7 +23,7 @@ impl<O: Committable> TxnLog<O> { " SELECT * FROM txn_log - ORDER BY timestamp ASC; + ORDER BY ROWID ASC; " ) .fetch_all(&app.database) diff --git a/crates/yt/src/storage/db/get/video/mod.rs b/crates/yt/src/storage/db/get/video/mod.rs index 69adb6b..c2edbdd 100644 --- a/crates/yt/src/storage/db/get/video/mod.rs +++ b/crates/yt/src/storage/db/get/video/mod.rs @@ -17,10 +17,13 @@ use yt_dlp::{info_json::InfoJson, json_cast, json_try_get}; use crate::{ app::App, - storage::db::video::{ - Video, VideoStatus, VideoStatusMarker, - comments::{Comments, raw::RawComment}, - video_from_record, + storage::db::{ + subscription::Subscription, + video::{ + Video, VideoStatus, VideoStatusMarker, + comments::{Comments, raw::RawComment}, + video_from_record, + }, }, }; @@ -187,6 +190,31 @@ impl Video { } } + pub(crate) async fn from_subscription(sub: &Subscription, app: &App) -> Result<Vec<Self>> { + debug!("Fetching videos from subscription: '{}'", sub.name); + + // NOTE: The ORDER BY statement should be the same as the one in [`next_to_download`]. <2024-08-22> + let videos = query!( + r" + SELECT * + FROM videos + WHERE parent_subscription_name = ? + ORDER BY priority DESC, publish_date DESC; + ", + sub.name + ) + .fetch_all(&app.database) + .await + .with_context(|| format!("Failed to query videos from subscription: '{}'", sub.name))?; + + let real_videos: Vec<Video> = videos + .iter() + .map(|base| -> Video { video_from_record!(base) }) + .collect(); + + Ok(real_videos) + } + /// Returns the videos that are in the `allowed_states`. /// /// # Panics diff --git a/crates/yt/src/storage/db/insert/playlist.rs b/crates/yt/src/storage/db/insert/playlist.rs index 4d3e140..dd8a9d2 100644 --- a/crates/yt/src/storage/db/insert/playlist.rs +++ b/crates/yt/src/storage/db/insert/playlist.rs @@ -40,17 +40,19 @@ impl Playlist { ) -> Result<()> { let (current_index, current_video) = self .get_focused_mut() - .expect("This should be some at this point"); + .expect("This should be some at this point"); // TODO: This expectation doesn't hold, if the video is marked as dropped before it is `quit`ed in the `yt watch` <2026-05-13> debug!( "Playlist handler will mark video '{}' {:?}.", current_video.title, new_state ); - match new_state { - VideoTransition::Watched => current_video.set_watched(ops), - VideoTransition::Picked => current_video.set_status(VideoStatus::Pick, ops), - } + let new_state = match new_state { + VideoTransition::Watched => VideoStatus::Watched, + VideoTransition::Picked => VideoStatus::Pick, + }; + current_video.remove_download_path(ops); + current_video.set_status(new_state, ops); self.save_watch_progress(mpv, current_index, ops); diff --git a/crates/yt/src/storage/db/insert/video/mod.rs b/crates/yt/src/storage/db/insert/video/mod.rs index da62e37..3c73ae7 100644 --- a/crates/yt/src/storage/db/insert/video/mod.rs +++ b/crates/yt/src/storage/db/insert/video/mod.rs @@ -597,14 +597,4 @@ impl Video { }); } } - - /// Mark this video watched. - /// This will both set the status to `Watched` and the `cache_path` to Null. - /// - /// # Panics - /// Only if assertions fail. - pub(crate) fn set_watched(&mut self, ops: &mut Operations<Operation>) { - self.remove_download_path(ops); - self.set_status(VideoStatus::Watched, ops); - } } diff --git a/crates/yt/src/storage/db/subscription.rs b/crates/yt/src/storage/db/subscription.rs index 403938e..39385b9 100644 --- a/crates/yt/src/storage/db/subscription.rs +++ b/crates/yt/src/storage/db/subscription.rs @@ -30,7 +30,11 @@ pub(crate) struct Subscription { impl Subscription { #[must_use] pub(crate) fn new(name: String, url: Url, is_active: bool) -> Self { - Self { name, url, is_active } + Self { + name, + url, + is_active, + } } } diff --git a/crates/yt/src/storage/db/video/comments/display.rs b/crates/yt/src/storage/db/video/comments/display.rs index c372603..d0c400d 100644 --- a/crates/yt/src/storage/db/video/comments/display.rs +++ b/crates/yt/src/storage/db/video/comments/display.rs @@ -33,7 +33,7 @@ impl Comments { color: bool, ) -> std::fmt::Result { let ident = &(0..ident_count).map(|_| " ").collect::<String>(); - let value = &comment.value; + let value = &comment.raw; f.write_str(ident)?; @@ -79,7 +79,7 @@ impl Comments { write!( f, " [{}]", - comment.value.like_count.bold().red().render(color) + comment.raw.like_count.bold().red().render(color) )?; f.write_str(":\n")?; @@ -102,7 +102,7 @@ impl Comments { f.write_str("\n")?; } else { let mut children = comment.replies.clone(); - children.sort_by(|a, b| a.value.timestamp.cmp(&b.value.timestamp)); + children.sort_by(|a, b| a.raw.timestamp.cmp(&b.raw.timestamp)); for child in children { format(&child, f, ident_count + 4, color)?; @@ -116,7 +116,7 @@ impl Comments { if !&self.inner.is_empty() { let mut children = self.inner.clone(); - children.sort_by(|a, b| b.value.like_count.cmp(&a.value.like_count)); + children.sort_by(|a, b| b.raw.like_count.cmp(&a.raw.like_count)); for child in children { format(&child, &mut f, 0, use_color)?; diff --git a/crates/yt/src/storage/db/video/comments/mod.rs b/crates/yt/src/storage/db/video/comments/mod.rs index 41a03be..b199346 100644 --- a/crates/yt/src/storage/db/video/comments/mod.rs +++ b/crates/yt/src/storage/db/video/comments/mod.rs @@ -8,11 +8,10 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::mem; +use log::debug; +use url::Url; -use regex::{Captures, Regex}; - -use crate::storage::db::video::comments::raw::{Parent, RawComment}; +use crate::storage::db::video::comments::raw::{Id, RawComment}; pub(crate) mod display; pub(crate) mod raw; @@ -20,182 +19,168 @@ pub(crate) mod raw; #[cfg(test)] mod tests; -#[derive(Debug, Clone, PartialEq)] -pub(crate) struct Comment { - value: RawComment, - replies: Vec<Self>, -} - #[derive(Debug, Default, PartialEq)] pub(crate) struct Comments { inner: Vec<Comment>, } +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct Comment { + raw: RawComment, + replies: Vec<Self>, +} + impl Comments { - pub(crate) fn from_raw(raw: Vec<RawComment>) -> Self { - let mut me = Self::default(); + pub(crate) fn from_raw(mut raw: Vec<RawComment>) -> Self { + let mut me = Self { inner: vec![] }; + + raw.iter_mut().enumerate().for_each(|(index, raw_comment)| { + raw_comment.original_order = index; + }); + + raw.sort_by_key(|raw| match &raw.parent { + raw::Parent::Root => 0, + raw::Parent::Id(id) => id.split('.').count(), + }); - // Apply the parent -> child mapping yt provides us with. for raw_comment in raw { - if let Parent::Id(id) = &raw_comment.parent { - me.insert(&(id.clone()), Comment::from(raw_comment)); - } else { - me.inner.push(Comment::from(raw_comment)); + match raw_comment.parent.clone() { + raw::Parent::Root => me.add_toplevel(raw_comment), + raw::Parent::Id(id) => { + let ids: Vec<_> = id.split('.').collect(); + me.add_reply(&ids, raw_comment); + } } } { // Sort the final comments chronologically. - // This ensures that replies are matched with the comment they actually replied to and - // not a later comment from the same author. - for comment in &mut me.inner { - comment - .replies - .sort_by_key(|comment| comment.value.timestamp); + // This reverses our sort we did before for ids. + me.sort_replies(); + } - for reply in &comment.replies { - assert!(reply.replies.is_empty()); - } + me + } + + fn sort_replies(&mut self) { + self.inner.sort_by_key(|comment| comment.raw.original_order); + + self.inner.iter_mut().for_each(Comment::sort_replies); + } + + fn add_toplevel(&mut self, comment: RawComment) { + self.inner.push(comment.into()); + } + + fn get_id(&mut self, id: &str) -> &mut Comment { + for comment in &mut self.inner { + if comment.raw.id.id == id { + return comment; } } - { - let find_reply_indicator = - Regex::new(r"\u{200b}?(@[^\t\s]+)\u{200b}?").expect("This is hardcoded"); + unreachable!("We cannot add a comment, that is a reply to an not-yet added one.") + } - // Try to re-construct the replies for the reply comments. - for comment in &mut me.inner { - let previous_replies = mem::take(&mut comment.replies); + fn add_reply(&mut self, ids: &[&str], mut raw_comment: RawComment) { + fn first_line(text: &str) -> &str { + let end = text + .chars() + .take_while(|ch| *ch != '\n' && *ch != '.') + .map(char::len_utf8) + .sum(); - let mut reply_tree = Comments::default(); + &text[..end] + } - for reply in previous_replies { - // We try to reconstruct the parent child relation ship by looking (naively) - // for a reply indicator. Currently, this is just the `@<some_name>`, as yt - // seems to insert that by default if you press `reply-to` in their clients. - // - // This follows these steps: - // - Does this reply have a “reply indicator”? - // - If yes, try to resolve the indicator. - // - If it is resolvable, add this reply to the [`Comment`] it resolved to. - // - If not, keep the comment as reply. + debug!("**Searching for parent id: `{}`", ids.join("-")); - if let Some(reply_indicator_matches) = - find_reply_indicator.captures(&reply.value.text.clone()) - { - // We found a reply indicator. - // First we traverse the current `reply_tree` in reversed order to find a - // match, than we check if the reply indicator matches the reply tree root - // and afterward we declare it unmatching and add it as toplevel. + let first = ids + .first() + .expect("We cannot have a comment reply, without also having it's parent id encoded"); + let mut reply = self.get_id(first); + debug!(" -> {}: `{}`", first, first_line(&reply.raw.text)); - let reply_target_author = reply_indicator_matches - .get(1) - .expect("This should also exist") - .as_str(); + for id in &ids[1..] { + debug!(" **Searching for id: `{id}`"); - if let Some(parent) = reply_tree.find_author_mut(reply_target_author) { - parent - .replies - .push(comment_from_reply(reply, &reply_indicator_matches)); - } else if comment.value.author == reply_target_author { - reply_tree - .add_toplevel(comment_from_reply(reply, &reply_indicator_matches)); - } else { - eprintln!( - "Failed to find a parent for ('{}') both directly \ - and via replies! The reply text was:\n'{}'\n", - reply_target_author, reply.value.text - ); - reply_tree.add_toplevel(reply); - } - } else { - // The comment text did not contain a reply indicator, so add it as - // toplevel. - reply_tree.add_toplevel(reply); - } - } + reply = reply.get_id(id); - comment.replies = reply_tree.inner; - } + debug!(" -> {}: `{}`", id, first_line(&reply.raw.text)); } - me - } - - fn add_toplevel(&mut self, value: Comment) { - self.inner.push(value); + raw_comment.text = raw_comment + .text + .trim() + .trim_start_matches(&reply.raw.author) + .trim() + .to_owned(); + reply.replies.push(raw_comment.into()); } +} - fn insert(&mut self, id: &str, value: Comment) { - let parent = self - .inner +impl Comment { + fn maybe_get_id(&mut self, id: &str) -> Option<&mut Self> { + self.replies .iter_mut() - .find(|c| c.value.id.id == id) - .expect("One of these should exist"); - - parent.replies.push(value); + .find(|comment| comment.raw.id.id == id) } - fn find_author_mut(&mut self, reply_target_author: &str) -> Option<&mut Comment> { - fn perform_check<'a>( - comment: &'a mut Comment, - reply_target_author: &str, - ) -> Option<&'a mut Comment> { - // TODO(@bpeetz): This is a workaround until rust has lexiographic lifetime support. <2025-07-18> - fn find_in_replies<'a>( - comment: &'a mut Comment, - reply_target_author: &str, - ) -> Option<&'a mut Comment> { - comment - .replies - .iter_mut() - .rev() - .find_map(|reply: &mut Comment| perform_check(reply, reply_target_author)) + fn get_id(&mut self, id: &str) -> &mut Self { + // TODO: This `if` is a work-around, until lexicographic lifetimes are added. <2026-05-26> + if self.maybe_get_id(id).is_none() { + macro_rules! from_last { + ($field:ident, $self:expr) => { + $self + .replies + .last() + .map_or(self.raw.$field, |last| last.raw.$field) + }; } - let comment_author_matches_target = comment.value.author == reply_target_author; - match find_in_replies(comment, reply_target_author) { - Some(_) => Some( - // PERFORMANCE(@bpeetz): We should not need to run this code twice. <2025-07-18> - find_in_replies(comment, reply_target_author) - .expect("We already had a Some result for this."), - ), - None if comment_author_matches_target => Some(comment), - None => None, - } - } + debug!( + "Failed to find an id for a reply (the parent id did not exist). Assuming deleted comment" + ); - for comment in self.inner.iter_mut().rev() { - if let Some(output) = perform_check(comment, reply_target_author) { - return Some(output); - } - } + self.replies.push(Comment { + raw: RawComment { + original_order: from_last!(original_order, self) + 1, + id: Id { id: id.to_owned() }, + text: "<Deleted comment>".to_owned(), + like_count: 0, + is_pinned: false, + author_id: "@ghost".to_owned(), + author: "@ghost".to_owned(), + author_is_verified: false, + author_thumbnail: Url::parse("https://example.org/@ghost").expect("hard-coded"), + parent: raw::Parent::Id(self.raw.id.id.clone()), + edited: false, + timestamp: from_last!(timestamp, self), + author_url: None, + author_is_uploader: false, + is_favorited: false, + }, + replies: vec![], + }); - None + self.replies.last_mut().expect("We just added it") + } else { + self.maybe_get_id(id).expect("It's some") + } } -} -fn comment_from_reply(reply: Comment, reply_indicator_matches: &Captures<'_>) -> Comment { - Comment::from(RawComment { - text: { - // Remove the `@<some_name>` for the comment text. - let full_match = reply_indicator_matches - .get(0) - .expect("This will always exist"); - let text = reply.value.text[0..full_match.start()].to_owned() - + &reply.value.text[full_match.end()..]; + fn sort_replies(&mut self) { + self.replies + .sort_by_key(|comment| comment.raw.original_order); - text.trim_matches(|c: char| c == '\u{200b}' || c == '\u{2060}' || c.is_whitespace()) - .to_owned() - }, - ..reply.value - }) + self.replies.iter_mut().for_each(Comment::sort_replies); + } } impl From<RawComment> for Comment { fn from(value: RawComment) -> Self { Self { - value, + raw: value, replies: vec![], } } diff --git a/crates/yt/src/storage/db/video/comments/raw.rs b/crates/yt/src/storage/db/video/comments/raw.rs index 3b7f40f..e27eedd 100644 --- a/crates/yt/src/storage/db/video/comments/raw.rs +++ b/crates/yt/src/storage/db/video/comments/raw.rs @@ -47,10 +47,15 @@ impl From<String> for Parent { #[derive(Debug, Deserialize, Clone, Eq, PartialEq, PartialOrd, Ord)] #[allow(clippy::struct_excessive_bools)] pub(crate) struct RawComment { + /// This field is used to encode the original order of the comments in the raw vector, returned + /// by yt-dlp. + #[serde(default = "zero")] + pub(crate) original_order: usize, + pub(crate) id: Id, pub(crate) text: String, #[serde(default = "zero")] - pub(crate) like_count: u32, + pub(crate) like_count: usize, pub(crate) is_pinned: bool, pub(crate) author_id: String, #[serde(default = "unknown")] @@ -71,7 +76,7 @@ pub(crate) struct RawComment { fn unknown() -> String { "<Unknown>".to_string() } -fn zero() -> u32 { +fn zero() -> usize { 0 } fn edited_from_time_text<'de, D>(d: D) -> Result<bool, D::Error> diff --git a/crates/yt/src/storage/db/video/comments/tests.rs b/crates/yt/src/storage/db/video/comments/tests.rs index 03e3597..8cb1a9a 100644 --- a/crates/yt/src/storage/db/video/comments/tests.rs +++ b/crates/yt/src/storage/db/video/comments/tests.rs @@ -38,6 +38,11 @@ macro_rules! mk_comments { ) )+ ) => {{ + use std::sync::atomic::{AtomicUsize, Ordering}; + + static INDEX_INPUT: AtomicUsize = AtomicUsize::new(0); + static INDEX_EXPECTED: AtomicUsize = AtomicUsize::new(0); + let (nested_input, _) = mk_comments!( $( $( @@ -49,7 +54,7 @@ macro_rules! mk_comments { let mut input: Vec<RawComment> = vec![ $( - mk_comments!(@to_raw input $name $comment $parent, $actual_parent) + mk_comments!(@to_raw input $name INDEX_INPUT.fetch_add(1, Ordering::Relaxed), $comment $parent, $actual_parent) ),+ ]; input.extend(nested_input); @@ -58,7 +63,7 @@ macro_rules! mk_comments { inner: vec![ $( Comment { - value: mk_comments!(@to_raw expected $name $comment $parent, $actual_parent), + raw: mk_comments!(@to_raw expected $name INDEX_EXPECTED.fetch_add(1, Ordering::Relaxed), $comment $parent, $actual_parent), replies: { let (_, nested_expected) = mk_comments!( $( @@ -86,6 +91,11 @@ macro_rules! mk_comments { ) )+ ) => {{ + use std::sync::atomic::{AtomicUsize, Ordering}; + + static INDEX_INPUT: AtomicUsize = AtomicUsize::new(0); + static INDEX_EXPECTED: AtomicUsize = AtomicUsize::new(0); + let (nested_input, _) = mk_comments!( $( $( @@ -97,7 +107,7 @@ macro_rules! mk_comments { let mut input: Vec<RawComment> = vec![ $( - mk_comments!(@to_raw input $name $comment) + mk_comments!(@to_raw input $name INDEX_INPUT.fetch_add(1, Ordering::Relaxed), $comment) ),+ ]; input.extend(nested_input); @@ -106,7 +116,7 @@ macro_rules! mk_comments { inner: vec![ $( Comment { - value: mk_comments!(@to_raw expected $name $comment), + raw: mk_comments!(@to_raw expected $name INDEX_EXPECTED.fetch_add(1, Ordering::Relaxed), $comment), replies: { let (_, nested_expected) = mk_comments!( $( @@ -125,19 +135,30 @@ macro_rules! mk_comments { (input, expected) }}; - (@mk_id $name:ident $comment:literal) => {{ + (@mk_id $name:ident $comment:literal $($parent:expr)?) => {{ use std::hash::{Hash, Hasher}; let input = format!("{}{}", stringify!($name), $comment); let mut digest = std::hash::DefaultHasher::new(); input.hash(&mut digest); - Id { id: digest.finish().to_string() } + + #[allow(unused_mut, unused_assignments)] + { + let mut parent_id = ".".to_owned(); + + $( + parent_id = format!("{}.", $parent.id); + )? + + Id { id: format!("{parent_id}{}", digest.finish().to_string()) } + } }}; - (@to_raw $state:ident $name:ident $comment:literal $($parent:expr, $actual_parent:ident)?) => { + (@to_raw $state:ident $name:ident $index:expr, $comment:literal $($parent:expr, $actual_parent:ident)?) => { RawComment { - id: mk_comments!(@mk_id $name $comment), + original_order: $index, + id: mk_comments!(@mk_id $name $comment $($parent)?), text: mk_comments!(@mk_text $state $comment $(, $actual_parent)?), like_count: 0, is_pinned: false, diff --git a/crates/yt/src/storage/db/video/mod.rs b/crates/yt/src/storage/db/video/mod.rs index deeb82c..7fc6764 100644 --- a/crates/yt/src/storage/db/video/mod.rs +++ b/crates/yt/src/storage/db/video/mod.rs @@ -10,7 +10,7 @@ use std::{fmt::Display, path::PathBuf, time::Duration}; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, TimeDelta, Utc}; use serde::{Deserialize, Serialize}; use url::Url; @@ -125,7 +125,7 @@ impl Display for Priority { } /// An UNIX time stamp. -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub(crate) struct TimeStamp { value: i64, } @@ -150,6 +150,15 @@ impl TimeStamp { } } } + +impl std::ops::Sub for TimeStamp { + type Output = TimeDelta; + + fn sub(self, rhs: Self) -> Self::Output { + TimeDelta::seconds(self.value - rhs.value) + } +} + impl Display for TimeStamp { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { DateTime::from_timestamp(self.value, 0) diff --git a/crates/yt_dlp/Cargo.toml b/crates/yt_dlp/Cargo.toml index eb2924d..7f2170e 100644 --- a/crates/yt_dlp/Cargo.toml +++ b/crates/yt_dlp/Cargo.toml @@ -28,7 +28,7 @@ pyo3 = { workspace = true } pyo3-pylogger = { path = "crates/pyo3-pylogger" } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true -thiserror = "2.0.17" +thiserror = "2.0.18" url.workspace = true [lints] diff --git a/crates/yt_dlp/crates/pyo3-pylogger/Cargo.toml b/crates/yt_dlp/crates/pyo3-pylogger/Cargo.toml index 89c827d..a2676e7 100644 --- a/crates/yt_dlp/crates/pyo3-pylogger/Cargo.toml +++ b/crates/yt_dlp/crates/pyo3-pylogger/Cargo.toml @@ -10,7 +10,7 @@ [package] name = "pyo3-pylogger" -version = "1.8.0" +version = "1.9.0" edition = "2021" authors = [ "Dylan Bobby Storey <dylan.storey@gmail.com>", diff --git a/crates/yt_dlp/crates/pyo3-pylogger/update.sh b/crates/yt_dlp/crates/pyo3-pylogger/update.sh deleted file mode 100755 index dd3e57e..0000000 --- a/crates/yt_dlp/crates/pyo3-pylogger/update.sh +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/env sh - -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2025 Dylan Bobby Storey <dylan.storey@gmail.com>, cpu <daniel@binaryparadox.net>, Warren Snipes <contact@warrensnipes.dev> -# SPDX-License-Identifier: Apache-2.0 -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -cd "$(dirname "$0")" || exit 1 -[ "$1" = "upgrade" ] && cargo upgrade --incompatible -cargo update - -# vim: ft=sh diff --git a/crates/yt_dlp/src/hooks.rs b/crates/yt_dlp/src/hooks.rs new file mode 100644 index 0000000..df70ecd --- /dev/null +++ b/crates/yt_dlp/src/hooks.rs @@ -0,0 +1,62 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +#[macro_export] +macro_rules! wrap_progress_hook { + ($name:ident, $new_name:ident) => { + yt_dlp::wrap_hook! {"progress_hook", $name, $new_name} + }; +} + +#[macro_export] +macro_rules! wrap_post_processor_hook { + ($name:ident, $new_name:ident) => { + yt_dlp::wrap_hook! {"post_processor_hook", $name, $new_name} + }; +} + +#[macro_export] +macro_rules! wrap_hook { + ($ty:literal, $name:ident, $new_name:ident) => { + pub(crate) fn $new_name( + py: yt_dlp::hooks::__priv::pyo3::Python<'_>, + ) -> yt_dlp::hooks::__priv::pyo3::PyResult< + yt_dlp::hooks::__priv::pyo3::Bound<'_, yt_dlp::hooks::__priv::pyo3::types::PyCFunction>, + > { + #[yt_dlp::hooks::__priv::pyo3::pyfunction] + #[pyo3(crate = "yt_dlp::hooks::__priv::pyo3")] + fn inner( + input: yt_dlp::hooks::__priv::pyo3::Bound< + '_, + yt_dlp::hooks::__priv::pyo3::types::PyDict, + >, + ) -> yt_dlp::hooks::__priv::pyo3::PyResult<()> { + let processed_input = { + let new_dict = yt_dlp::hooks::__priv::filter_dict(input); + yt_dlp::hooks::__priv::json_dumps(&new_dict) + }; + + $name(processed_input)?; + + Ok(()) + } + + let module = yt_dlp::hooks::__priv::pyo3::types::PyModule::new(py, $ty)?; + let fun = yt_dlp::hooks::__priv::pyo3::wrap_pyfunction!(inner, module)?; + + Ok(fun) + } + }; +} + +pub mod __priv { + pub use crate::info_json::{json_dumps, json_loads, filter_dict}; + pub use pyo3; +} diff --git a/crates/yt_dlp/src/info_json.rs b/crates/yt_dlp/src/info_json.rs index 402acb4..df49218 100644 --- a/crates/yt_dlp/src/info_json.rs +++ b/crates/yt_dlp/src/info_json.rs @@ -54,3 +54,39 @@ pub fn json_dumps(input: &Bound<'_, PyDict>) -> serde_json::Map<String, serde_js _ => unreachable!("These should not be json.dumps output"), } } + +/// # Panics +/// If expectation about python operations fail. +#[must_use] +pub fn filter_dict(input: Bound<'_, PyDict>) -> Bound<'_, PyDict> { + let new_dict = PyDict::new(input.py()); + + input + .into_iter() + .filter_map(|(name, value)| { + let real_name = name.extract::<String>().expect("Should always be a string"); + + if real_name.starts_with('_') { + None + } else { + let value = if value.is_instance_of::<PyDict>() { + filter_dict( + value + .cast_into::<PyDict>() + .expect("to be a dict, because we checked"), + ) + .into_any() + } else { + value + }; + Some((real_name, value)) + } + }) + .for_each(|(key, value)| { + new_dict + .set_item(&key, value) + .expect("This is a transposition, should always be valid"); + }); + + new_dict +} diff --git a/crates/yt_dlp/src/lib.rs b/crates/yt_dlp/src/lib.rs index 4b252de..abe766d 100644 --- a/crates/yt_dlp/src/lib.rs +++ b/crates/yt_dlp/src/lib.rs @@ -27,7 +27,7 @@ use crate::{ pub mod info_json; pub mod options; pub mod post_processors; -pub mod progress_hook; +pub mod hooks; pub mod python_error; #[macro_export] diff --git a/crates/yt_dlp/src/options.rs b/crates/yt_dlp/src/options.rs index 4b8906e..a87473d 100644 --- a/crates/yt_dlp/src/options.rs +++ b/crates/yt_dlp/src/options.rs @@ -21,7 +21,7 @@ use crate::{ python_error::{IntoPythonError, PythonError}, }; -pub type ProgressHookFunction = fn(py: Python<'_>) -> PyResult<Bound<'_, PyCFunction>>; +pub type HookFunction = fn(py: Python<'_>) -> PyResult<Bound<'_, PyCFunction>>; pub type PostProcessorFunction = fn(py: Python<'_>) -> PyResult<Bound<'_, PyAny>>; /// Options, that are used to customize the download behaviour. @@ -32,7 +32,8 @@ pub type PostProcessorFunction = fn(py: Python<'_>) -> PyResult<Bound<'_, PyAny> #[derive(Default, Debug)] pub struct YoutubeDLOptions { options: serde_json::Map<String, serde_json::Value>, - progress_hook: Option<ProgressHookFunction>, + progress_hook: Option<HookFunction>, + post_processor_hook: Option<HookFunction>, post_processors: Vec<PostProcessorFunction>, } @@ -42,6 +43,7 @@ impl YoutubeDLOptions { let me = Self { options: serde_json::Map::new(), progress_hook: None, + post_processor_hook: None, post_processors: vec![], }; @@ -57,7 +59,7 @@ impl YoutubeDLOptions { } #[must_use] - pub fn with_progress_hook(self, progress_hook: ProgressHookFunction) -> Self { + pub fn with_progress_hook(self, progress_hook: HookFunction) -> Self { if let Some(_previous_hook) = self.progress_hook { todo!() } else { @@ -67,6 +69,17 @@ impl YoutubeDLOptions { } } } + #[must_use] + pub fn with_post_processor_hook(self, post_processor_hook: HookFunction) -> Self { + if let Some(_previous_hook) = self.post_processor_hook { + todo!() + } else { + Self { + post_processor_hook: Some(post_processor_hook), + ..self + } + } + } #[must_use] pub fn with_post_processor(mut self, pp: PostProcessorFunction) -> Self { @@ -135,6 +148,15 @@ signal.signal(signal.SIGINT, signal.SIG_DFL) opts.set_item(intern!(py, "progress_hooks"), vec![ph(py).wrap_exc(py)?]) .wrap_exc(py)?; } + + // Setup the post_processor hook + if let Some(ph) = options.post_processor_hook { + opts.set_item( + intern!(py, "postprocessor_hooks"), + vec![ph(py).wrap_exc(py)?], + ) + .wrap_exc(py)?; + } } { diff --git a/crates/yt_dlp/src/post_processors/dearrow.rs b/crates/yt_dlp/src/post_processors/dearrow.rs index 7787d68..ff4cdfa 100644 --- a/crates/yt_dlp/src/post_processors/dearrow.rs +++ b/crates/yt_dlp/src/post_processors/dearrow.rs @@ -9,7 +9,7 @@ // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. use curl::easy::Easy; -use log::{error, info, trace, warn}; +use log::{info, trace, warn}; use pyo3::{ Bound, PyAny, PyErr, PyResult, Python, exceptions, intern, pyfunction, types::{PyAnyMethods, PyDict, PyModule}, diff --git a/crates/yt_dlp/src/progress_hook.rs b/crates/yt_dlp/src/progress_hook.rs deleted file mode 100644 index 7e5f8a5..0000000 --- a/crates/yt_dlp/src/progress_hook.rs +++ /dev/null @@ -1,67 +0,0 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -#[macro_export] -macro_rules! wrap_progress_hook { - ($name:ident, $new_name:ident) => { - pub(crate) fn $new_name( - py: yt_dlp::progress_hook::__priv::pyo3::Python<'_>, - ) -> yt_dlp::progress_hook::__priv::pyo3::PyResult< - yt_dlp::progress_hook::__priv::pyo3::Bound< - '_, - yt_dlp::progress_hook::__priv::pyo3::types::PyCFunction, - >, - > { - #[yt_dlp::progress_hook::__priv::pyo3::pyfunction] - #[pyo3(crate = "yt_dlp::progress_hook::__priv::pyo3")] - fn inner( - input: yt_dlp::progress_hook::__priv::pyo3::Bound< - '_, - yt_dlp::progress_hook::__priv::pyo3::types::PyDict, - >, - ) -> yt_dlp::progress_hook::__priv::pyo3::PyResult<()> { - let processed_input = { - let new_dict = yt_dlp::progress_hook::__priv::pyo3::types::PyDict::new(input.py()); - - input - .into_iter() - .filter_map(|(name, value)| { - let real_name = yt_dlp::progress_hook::__priv::pyo3::types::PyAnyMethods::extract::<String>(&name).expect("Should always be a string"); - - if real_name.starts_with('_') { - None - } else { - Some((real_name, value)) - } - }) - .for_each(|(key, value)| { - yt_dlp::progress_hook::__priv::pyo3::types::PyDictMethods::set_item(&new_dict, &key, value) - .expect("This is a transpositions, should always be valid"); - }); - yt_dlp::progress_hook::__priv::json_dumps(&new_dict) - }; - - $name(processed_input)?; - - Ok(()) - } - - let module = yt_dlp::progress_hook::__priv::pyo3::types::PyModule::new(py, "progress_hook")?; - let fun = yt_dlp::progress_hook::__priv::pyo3::wrap_pyfunction!(inner, module)?; - - Ok(fun) - } - }; -} - -pub mod __priv { - pub use crate::info_json::{json_dumps, json_loads}; - pub use pyo3; -} diff --git a/crates/yt_dlp/update.sh b/crates/yt_dlp/update.sh deleted file mode 100755 index 52c96b5..0000000 --- a/crates/yt_dlp/update.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -"$(dirname "$0")/crates/pyo3-pylogger/update.sh" "$@" @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1764245472, - "narHash": "sha256-udCSZoKawLiNJKFQgikkN96tvVJggs61ihRq8sRt8tM=", + "lastModified": 1780981259, + "narHash": "sha256-GVdFp/OsVrwtvNe5f/o4PAv31sjxykYH3Kp2zIyJTeg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6c16b7ce10e5ef1fee3aecfb327be61888818a7a", + "rev": "58f254b2fae09cec435a9480741ba3c749c4e1b6", "type": "github" }, "original": { @@ -29,11 +29,11 @@ ] }, "locked": { - "lastModified": 1762938485, - "narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=", + "lastModified": 1780220602, + "narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4", + "rev": "db947814a175b7ca6ded66e21383d938df01c227", "type": "github" }, "original": { @@ -84,7 +84,7 @@ pkgs.clippy pkgs.rustc pkgs.rustfmt - pkgs.mold-wrapped + pkgs.mold pkgs.cargo-edit pkgs.cargo-expand diff --git a/tree-sitter-yts/.editorconfig b/tree-sitter-yts/.editorconfig index 9975ff2..ff17b12 100644 --- a/tree-sitter-yts/.editorconfig +++ b/tree-sitter-yts/.editorconfig @@ -1,24 +1,50 @@ -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +root = true -# for testing purposes, the corpus may have trailing whitespace -# and may have mixed EOL. -# Still want a final newline though, as that makes no semantic difference. -[corpus/*] -trim_trailing_whitespace = false -end_of_line = unset +[*] +charset = utf-8 -[**.{js,json,cc,css}] +[*.{json,toml,yml,gyp,xml}] indent_style = space indent_size = 2 -# tree-sitter generate emits json with no trailing newline -[src/node-types.json] -insert_final_newline = false +[*.{js,ts}] +indent_style = space +indent_size = 2 + +[*.scm] +indent_style = space +indent_size = 2 + +[*.{c,cc,h}] +indent_style = space +indent_size = 4 + +[*.rs] +indent_style = space +indent_size = 4 + +[*.{py,pyi}] +indent_style = space +indent_size = 4 + +[*.swift] +indent_style = space +indent_size = 4 + +[*.java] +indent_style = space +indent_size = 4 + +[*.go] +indent_style = tab +indent_size = 8 + +[Makefile] +indent_style = tab +indent_size = 8 + +[parser.c] +indent_size = 2 + +[{alloc,array,parser}.h] +indent_size = 2 diff --git a/tree-sitter-yts/.gitattributes b/tree-sitter-yts/.gitattributes new file mode 100644 index 0000000..027ac70 --- /dev/null +++ b/tree-sitter-yts/.gitattributes @@ -0,0 +1,46 @@ +* text=auto eol=lf + +# Generated source files +src/*.json linguist-generated +src/parser.c linguist-generated +src/tree_sitter/* linguist-generated + +# C bindings +bindings/c/** linguist-generated +CMakeLists.txt linguist-generated +Makefile linguist-generated + +# Rust bindings +bindings/rust/* linguist-generated +Cargo.toml linguist-generated +Cargo.lock linguist-generated + +# Node.js bindings +bindings/node/* linguist-generated +binding.gyp linguist-generated +package.json linguist-generated +package-lock.json linguist-generated + +# Python bindings +bindings/python/** linguist-generated +setup.py linguist-generated +pyproject.toml linguist-generated + +# Go bindings +bindings/go/* linguist-generated +go.mod linguist-generated +go.sum linguist-generated + +# Swift bindings +bindings/swift/** linguist-generated +Package.swift linguist-generated +Package.resolved linguist-generated + +# Zig bindings +bindings/zig/* linguist-generated +build.zig linguist-generated +build.zig.zon linguist-generated + +# Java bindings +pom.xml linguist-generated +bindings/java/** linguist-generated diff --git a/tree-sitter-yts/.gitignore b/tree-sitter-yts/.gitignore index 88a62ca..7c0cb7f 100644 --- a/tree-sitter-yts/.gitignore +++ b/tree-sitter-yts/.gitignore @@ -1,11 +1,48 @@ -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +# Rust artifacts +target/ -/node_modules +# Node artifacts +build/ +prebuilds/ +node_modules/ + +# Swift artifacts +.build/ + +# Go artifacts +_obj/ + +# Python artifacts +.venv/ +dist/ +*.egg-info +*.whl + +# C artifacts +*.a +*.so +*.so.* +*.dylib +*.dll +*.pc +*.exp +*.lib + +# Zig artifacts +.zig-cache/ +zig-cache/ +zig-out/ + +# Example dirs +/examples/*/ + +# Grammar volatiles +*.wasm +*.obj +*.o + +# Archives +*.tar.gz +*.tgz +*.zip +*.jar diff --git a/tree-sitter-yts/Cargo.toml b/tree-sitter-yts/Cargo.toml index 1872f18..a6c259c 100644 --- a/tree-sitter-yts/Cargo.toml +++ b/tree-sitter-yts/Cargo.toml @@ -1,31 +1,34 @@ -# yt - A fully featured command line YouTube client -# -# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of Yt. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - [package] name = "tree-sitter-yts" -description = "yts grammar for the tree-sitter parsing library" -version = "0.0.1" -keywords = ["incremental", "parsing", "yts"] -categories = ["parsing", "text-editors"] -repository = "https://github.com/tree-sitter/tree-sitter-yts" -edition = "2018" -license = "MIT" +description = "Parser for yt's selection language" +version = "0.1.0" +authors = ["Benedikt Peetz <benedikt.peetz@b-peetz.de>"] +license = "GPL-3-or-later" +readme = "README.md" +keywords = ["incremental", "parsing", "tree-sitter", "yts"] +categories = ["parser-implementations", "parsing", "text-editors"] +repository = "https://git.foss-syndicate.org/bpeetz/clients/yt" +edition = "2021" +autoexamples = false build = "bindings/rust/build.rs" -include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"] +include = [ + "bindings/rust/*", + "grammar.js", + "queries/*", + "src/*", + "tree-sitter.json", + "/LICENSE", +] [lib] path = "bindings/rust/lib.rs" [dependencies] -tree-sitter = "~0.20.10" +tree-sitter-language = "0.1" [build-dependencies] -cc = "1.0" +cc = "1.2" + +[dev-dependencies] +tree-sitter = "0.26.8" diff --git a/tree-sitter-yts/binding.gyp b/tree-sitter-yts/binding.gyp deleted file mode 100644 index b05038b..0000000 --- a/tree-sitter-yts/binding.gyp +++ /dev/null @@ -1,19 +0,0 @@ -{ - "targets": [ - { - "target_name": "tree_sitter_yts_binding", - "include_dirs": [ - "<!(node -e \"require('nan')\")", - "src" - ], - "sources": [ - "bindings/node/binding.cc", - "src/parser.c", - # If your language uses an external scanner, add it here. - ], - "cflags_c": [ - "-std=c99", - ] - } - ] -} diff --git a/tree-sitter-yts/binding.gyp.license b/tree-sitter-yts/binding.gyp.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/binding.gyp.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/tree-sitter-yts/bindings/node/binding.cc b/tree-sitter-yts/bindings/node/binding.cc deleted file mode 100644 index fdf44ff..0000000 --- a/tree-sitter-yts/bindings/node/binding.cc +++ /dev/null @@ -1,43 +0,0 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -#include "nan.h" -#include "tree_sitter/parser.h" -#include <node.h> - -using namespace v8; - -extern "C" TSLanguage *tree_sitter_yts (); - -namespace -{ - -NAN_METHOD (New) {} - -void -Init (Local<Object> exports, Local<Object> module) -{ - Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate> (New); - tpl->SetClassName (Nan::New ("Language").ToLocalChecked ()); - tpl->InstanceTemplate ()->SetInternalFieldCount (1); - - Local<Function> constructor = Nan::GetFunction (tpl).ToLocalChecked (); - Local<Object> instance - = constructor->NewInstance (Nan::GetCurrentContext ()).ToLocalChecked (); - Nan::SetInternalFieldPointer (instance, 0, tree_sitter_yts ()); - - Nan::Set (instance, Nan::New ("name").ToLocalChecked (), - Nan::New ("yts").ToLocalChecked ()); - Nan::Set (module, Nan::New ("exports").ToLocalChecked (), instance); -} - -NODE_MODULE (tree_sitter_yts_binding, Init) - -} // namespace diff --git a/tree-sitter-yts/bindings/node/index.js b/tree-sitter-yts/bindings/node/index.js deleted file mode 100644 index 580bda0..0000000 --- a/tree-sitter-yts/bindings/node/index.js +++ /dev/null @@ -1,29 +0,0 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -try { - module.exports = require("../../build/Release/tree_sitter_yts_binding"); -} catch (error1) { - if (error1.code !== "MODULE_NOT_FOUND") { - throw error1; - } - try { - module.exports = require("../../build/Debug/tree_sitter_yts_binding"); - } catch (error2) { - if (error2.code !== "MODULE_NOT_FOUND") { - throw error2; - } - throw error1; - } -} - -try { - module.exports.nodeTypeInfo = require("../../src/node-types.json"); -} catch (_) {} diff --git a/tree-sitter-yts/bindings/rust/build.rs b/tree-sitter-yts/bindings/rust/build.rs index 075dc92..95250d7 100644 --- a/tree-sitter-yts/bindings/rust/build.rs +++ b/tree-sitter-yts/bindings/rust/build.rs @@ -1,50 +1,56 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - fn main() { let src_dir = std::path::Path::new("src"); let mut c_config = cc::Build::new(); - c_config.include(&src_dir); - c_config - .flag_if_supported("-Wno-unused-parameter") - .flag_if_supported("-Wno-unused-but-set-variable") - .flag_if_supported("-Wno-trigraphs"); - let parser_path = src_dir.join("parser.c"); - c_config.file(&parser_path); + c_config.std("c11").include(src_dir); - // If your language uses an external scanner written in C, - // then include this block of code: + #[cfg(target_env = "msvc")] + c_config.flag("-utf-8"); - /* - let scanner_path = src_dir.join("scanner.c"); - c_config.file(&scanner_path); - println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); - */ + if std::env::var("TARGET").unwrap() == "wasm32-unknown-unknown" { + let Ok(wasm_headers) = std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS") else { + panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS must be set by the language crate"); + }; + let Ok(wasm_src) = + std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_SRC").map(std::path::PathBuf::from) + else { + panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_SRC must be set by the language crate"); + }; + + c_config.include(&wasm_headers); + c_config.files([ + wasm_src.join("stdio.c"), + wasm_src.join("stdlib.c"), + wasm_src.join("string.c"), + ]); + } - c_config.compile("parser"); + let parser_path = src_dir.join("parser.c"); + c_config.file(&parser_path); println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); - // If your language uses an external scanner written in C++, - // then include this block of code: + let scanner_path = src_dir.join("scanner.c"); + if scanner_path.exists() { + c_config.file(&scanner_path); + println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); + } + + c_config.compile("tree-sitter-yts"); - /* - let mut cpp_config = cc::Build::new(); - cpp_config.cpp(true); - cpp_config.include(&src_dir); - cpp_config - .flag_if_supported("-Wno-unused-parameter") - .flag_if_supported("-Wno-unused-but-set-variable"); - let scanner_path = src_dir.join("scanner.cc"); - cpp_config.file(&scanner_path); - cpp_config.compile("scanner"); - println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); - */ + println!("cargo:rustc-check-cfg=cfg(with_highlights_query)"); + if !"queries/highlights.scm".is_empty() && std::path::Path::new("queries/highlights.scm").exists() { + println!("cargo:rustc-cfg=with_highlights_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_injections_query)"); + if !"queries/injections.scm".is_empty() && std::path::Path::new("queries/injections.scm").exists() { + println!("cargo:rustc-cfg=with_injections_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_locals_query)"); + if !"queries/locals.scm".is_empty() && std::path::Path::new("queries/locals.scm").exists() { + println!("cargo:rustc-cfg=with_locals_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_tags_query)"); + if !"queries/tags.scm".is_empty() && std::path::Path::new("queries/tags.scm").exists() { + println!("cargo:rustc-cfg=with_tags_query"); + } } diff --git a/tree-sitter-yts/bindings/rust/lib.rs b/tree-sitter-yts/bindings/rust/lib.rs index 0880238..35f14ce 100644 --- a/tree-sitter-yts/bindings/rust/lib.rs +++ b/tree-sitter-yts/bindings/rust/lib.rs @@ -1,54 +1,52 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -//! This crate provides yts language support for the [tree-sitter][] parsing library. +//! This crate provides YTS language support for the [tree-sitter] parsing library. //! -//! Typically, you will use the [language][language func] function to add this language to a -//! tree-sitter [Parser][], and then use the parser to parse some code: +//! Typically, you will use the [`LANGUAGE`] constant to add this language to a +//! tree-sitter [`Parser`], and then use the parser to parse some code: //! //! ``` -//! let code = ""; +//! let code = r#" +//! "#; //! let mut parser = tree_sitter::Parser::new(); -//! parser.set_language(tree_sitter_yts::language()).expect("Error loading yts grammar"); +//! let language = tree_sitter_YTS::LANGUAGE; +//! parser +//! .set_language(&language.into()) +//! .expect("Error loading YTS parser"); //! let tree = parser.parse(code, None).unwrap(); +//! assert!(!tree.root_node().has_error()); //! ``` //! -//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -//! [language func]: fn.language.html -//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html +//! [`Parser`]: https://docs.rs/tree-sitter/0.26.8/tree_sitter/struct.Parser.html //! [tree-sitter]: https://tree-sitter.github.io/ -use tree_sitter::Language; +use tree_sitter_language::LanguageFn; extern "C" { - fn tree_sitter_yts() -> Language; + fn tree_sitter_YTS() -> *const (); } -/// Get the tree-sitter [Language][] for this grammar. -/// -/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html -pub fn language() -> Language { - unsafe { tree_sitter_yts() } -} +/// The tree-sitter [`LanguageFn`] for this grammar. +pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_YTS) }; -/// The content of the [`node-types.json`][] file for this grammar. +/// The content of the [`node-types.json`] file for this grammar. /// -/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types -pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json"); +/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types +pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); + +#[cfg(with_highlights_query)] +/// The syntax highlighting query for this grammar. +pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); + +#[cfg(with_injections_query)] +/// The language injection query for this grammar. +pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); -// Uncomment these to include any queries that this grammar contains +#[cfg(with_locals_query)] +/// The local variable query for this grammar. +pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); -// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm"); -// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm"); -// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm"); -// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm"); +#[cfg(with_tags_query)] +/// The symbol tagging query for this grammar. +pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); #[cfg(test)] mod tests { @@ -56,7 +54,7 @@ mod tests { fn test_can_load_grammar() { let mut parser = tree_sitter::Parser::new(); parser - .set_language(super::language()) - .expect("Error loading yts language"); + .set_language(&super::LANGUAGE.into()) + .expect("Error loading YTS parser"); } } diff --git a/tree-sitter-yts/grammar.js b/tree-sitter-yts/grammar.js index 7576228..cf76d78 100644 --- a/tree-sitter-yts/grammar.js +++ b/tree-sitter-yts/grammar.js @@ -1,14 +1,13 @@ -// yt - A fully featured command line YouTube client -// -// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Yt. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +/** + * @file Parser for yt's selection language + * @author Benedikt Peetz <benedikt.peetz@b-peetz.de> + * @license GPL-3-or-later + */ -module.exports = grammar({ +/// <reference types="tree-sitter-cli/dsl" /> +// @ts-check + +export default grammar({ name: "yts", rules: { diff --git a/tree-sitter-yts/highlight_sample.yts b/tree-sitter-yts/highlight_sample.yts deleted file mode 100644 index 7f75852..0000000 --- a/tree-sitter-yts/highlight_sample.yts +++ /dev/null @@ -1,7 +0,0 @@ -pick 6a21 "Name" "2024-01-17" "A" "0h 00m" "url" -pick 6z81 "Name2" "2024-01-16" "A2" "0h 00m" "url2" -pick 6b84 "Name3" "2024-01-16" "A3" "0h 00m" "url3" -pick 6f06 "Name4" "2024-01-16" "A4" "299h 36m" "url4" -watch --priority="-100" --speed 1 6z21 "Name" "2024-01-17" "A" "0m 0s" "url" -watch -s 2 -l 'en,gr,fr' 61f1 "Name2" "2024-01-16" "A2" "0m 0s" "url" -watch -s=2 -l='en,gr,fr' 61f1 "Name2" "2024-01-16" "A2" "0m 0s" "url" diff --git a/tree-sitter-yts/highlight_sample.yts.license b/tree-sitter-yts/highlight_sample.yts.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/highlight_sample.yts.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/tree-sitter-yts/package.json b/tree-sitter-yts/package.json index 5bd57c0..43eb988 100644 --- a/tree-sitter-yts/package.json +++ b/tree-sitter-yts/package.json @@ -1,19 +1,56 @@ { "name": "tree-sitter-yts", - "version": "0.0.1", - "description": "yts grammar for tree-sitter", + "version": "0.1.0", + "description": "Parser for yt's selection language", + "type": "module", + "repository": { + "type": "git", + "url": "git+https://git.foss-syndicate.org/bpeetz/clients/yt.git" + }, + "license": "GPL-3-or-later", + "author": { + "name": "Benedikt Peetz", + "email": "benedikt.peetz@b-peetz.de" + }, "main": "bindings/node", + "types": "bindings/node", "keywords": [ + "incremental", "parsing", - "incremental" + "tree-sitter", + "yts" + ], + "files": [ + "grammar.js", + "tree-sitter.json", + "binding.gyp", + "prebuilds/**", + "bindings/node/*", + "queries/*", + "src/**", + "*.wasm" ], "dependencies": { - "nan": "^2.12.1" + "node-addon-api": "^8.5.0", + "node-gyp-build": "^4.8.4" }, "devDependencies": { - "tree-sitter-cli": "^0.20.8" + "prebuildify": "^6.0.1", + "tree-sitter": "^0.25.0", + "tree-sitter-cli": "^0.26.8" + }, + "peerDependencies": { + "tree-sitter": "^0.25.0" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } }, "scripts": { - "test": "tree-sitter test" + "install": "node-gyp-build", + "prestart": "tree-sitter build --wasm", + "start": "tree-sitter playground", + "test": "node --test bindings/node/*_test.js" } } diff --git a/tree-sitter-yts/package.json.license b/tree-sitter-yts/package.json.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/package.json.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/tree-sitter-yts/package.nix b/tree-sitter-yts/package.nix index 3a0f8f6..6582d64 100644 --- a/tree-sitter-yts/package.nix +++ b/tree-sitter-yts/package.nix @@ -8,60 +8,11 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. { - stdenv, - nodejs, tree-sitter, - lib, }: -# # Build a parser grammar and put the resulting shared object in `$out/parser` -# { -# # language name -# language ? "yts", -# version ? "1.0.0", -# src ? ./., -# location ? null, -# generate ? false, -# ... -# } @ args: -stdenv.mkDerivation { - pname = "yts-grammar"; - version = "1.0.0"; +tree-sitter.buildGrammar { + language = "yts"; + version = "0.1.0"; src = ./.; - - nativeBuildInputs = [nodejs tree-sitter]; - - CFLAGS = ["-Isrc" "-O2"]; - CXXFLAGS = ["-Isrc" "-O2"]; - - stripDebugList = ["parser"]; - - configurePhase = '' - tree-sitter generate - ''; - - # When both scanner.{c,cc} exist, we should not link both since they may be the same but in - # different languages. Just randomly prefer C++ if that happens. - buildPhase = '' - runHook preBuild - if [[ -e src/scanner.cc ]]; then - $CXX -fPIC -c src/scanner.cc -o scanner.o $CXXFLAGS - elif [[ -e src/scanner.c ]]; then - $CC -fPIC -c src/scanner.c -o scanner.o $CFLAGS - fi - $CC -fPIC -c src/parser.c -o parser.o $CFLAGS - rm -rf parser - $CXX -shared -o parser *.o - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - mkdir $out - mv parser $out/ - if [[ -d queries ]]; then - cp -r queries $out - fi - runHook postInstall - ''; } diff --git a/tree-sitter-yts/src/grammar.json b/tree-sitter-yts/src/grammar.json index f2f337c..b979e83 100644 --- a/tree-sitter-yts/src/grammar.json +++ b/tree-sitter-yts/src/grammar.json @@ -3,307 +3,8 @@ "name": "yts", "rules": { "source_file": { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "line" - }, - { - "type": "SYMBOL", - "name": "comment" - } - ] - } - }, - "line": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "command" - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "flag" - } - }, - { - "type": "SYMBOL", - "name": "id" - }, - { - "type": "SYMBOL", - "name": "title" - }, - { - "type": "SYMBOL", - "name": "date" - }, - { - "type": "SYMBOL", - "name": "author" - }, - { - "type": "SYMBOL", - "name": "duration" - }, - { - "type": "SYMBOL", - "name": "url" - }, - { - "type": "STRING", - "value": "\n" - } - ] - }, - "command": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "pick" - }, - { - "type": "STRING", - "value": "p" - }, - { - "type": "STRING", - "value": "watch" - }, - { - "type": "STRING", - "value": "w" - }, - { - "type": "STRING", - "value": "watched" - }, - { - "type": "STRING", - "value": "wd" - }, - { - "type": "STRING", - "value": "add" - }, - { - "type": "STRING", - "value": "a" - }, - { - "type": "STRING", - "value": "drop" - }, - { - "type": "STRING", - "value": "d" - }, - { - "type": "STRING", - "value": "url" - }, - { - "type": "STRING", - "value": "u" - } - ] - }, - "flag": { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "-\\w [^\\s]+" - }, - { - "type": "PATTERN", - "value": "-\\w '[^']*'" - }, - { - "type": "PATTERN", - "value": "-\\w \"[^\"]*\"" - }, - { - "type": "PATTERN", - "value": "-\\w=[^\\s]+" - }, - { - "type": "PATTERN", - "value": "-\\w='[^']*'" - }, - { - "type": "PATTERN", - "value": "-\\w=\"[^\"]*\"" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+ [^\\s]+" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+ '[^']*'" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+ \"[^\"]*\"" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+=[^\\s]+" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+='[^']*'" - }, - { - "type": "PATTERN", - "value": "--\\w[\\w-]+=\"[^\"]*\"" - } - ] - }, - "id": { - "type": "PATTERN", - "value": "[a-z0-9]+" - }, - "title": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "date": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "[No release date]" - }, - { - "type": "PATTERN", - "value": "\\d{4}-\\d{2}-\\d{2}" - } - ] - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "author": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "[No author]" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - } - ] - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "duration": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": "[No duration]" - }, - { - "type": "PATTERN", - "value": "\\d+m \\d+s" - }, - { - "type": "PATTERN", - "value": "\\d+h \\d+m" - } - ] - } - ] - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "url": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_q" - }, - { - "type": "PATTERN", - "value": "[^\"]+" - }, - { - "type": "SYMBOL", - "name": "_q" - } - ] - }, - "comment": { - "type": "PATTERN", - "value": "#.*" - }, - "_q": { - "type": "SYMBOL", - "name": "quote" - }, - "quote": { - "type": "PATTERN", - "value": "\"" + "type": "STRING", + "value": "hello" } }, "extras": [ @@ -316,5 +17,6 @@ "precedences": [], "externals": [], "inline": [], - "supertypes": [] -} + "supertypes": [], + "reserved": {} +}
\ No newline at end of file diff --git a/tree-sitter-yts/src/grammar.json.license b/tree-sitter-yts/src/grammar.json.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/src/grammar.json.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/tree-sitter-yts/src/node-types.json b/tree-sitter-yts/src/node-types.json index 809eb38..cd69f6e 100644 --- a/tree-sitter-yts/src/node-types.json +++ b/tree-sitter-yts/src/node-types.json @@ -1,226 +1,12 @@ [ { - "type": "author", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "command", - "named": true, - "fields": {} - }, - { - "type": "date", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "duration", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "flag", - "named": true, - "fields": {} - }, - { - "type": "line", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "author", - "named": true - }, - { - "type": "command", - "named": true - }, - { - "type": "date", - "named": true - }, - { - "type": "duration", - "named": true - }, - { - "type": "flag", - "named": true - }, - { - "type": "id", - "named": true - }, - { - "type": "title", - "named": true - }, - { - "type": "url", - "named": true - } - ] - } - }, - { "type": "source_file", "named": true, "root": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "comment", - "named": true - }, - { - "type": "line", - "named": true - } - ] - } - }, - { - "type": "title", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "url", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": true, - "types": [ - { - "type": "quote", - "named": true - } - ] - } - }, - { - "type": "\n", - "named": false - }, - { - "type": "[No author]", - "named": false - }, - { - "type": "[No duration]", - "named": false - }, - { - "type": "[No release date]", - "named": false - }, - { - "type": "a", - "named": false - }, - { - "type": "add", - "named": false - }, - { - "type": "comment", - "named": true - }, - { - "type": "d", - "named": false - }, - { - "type": "drop", - "named": false - }, - { - "type": "id", - "named": true - }, - { - "type": "p", - "named": false - }, - { - "type": "pick", - "named": false - }, - { - "type": "quote", - "named": true - }, - { - "type": "u", - "named": false - }, - { - "type": "url", - "named": false - }, - { - "type": "w", - "named": false - }, - { - "type": "watch", - "named": false - }, - { - "type": "watched", - "named": false + "fields": {} }, { - "type": "wd", + "type": "hello", "named": false } -] +]
\ No newline at end of file diff --git a/tree-sitter-yts/src/node-types.json.license b/tree-sitter-yts/src/node-types.json.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/src/node-types.json.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/tree-sitter-yts/src/parser.c b/tree-sitter-yts/src/parser.c index 9552850..95f9999 100644 --- a/tree-sitter-yts/src/parser.c +++ b/tree-sitter-yts/src/parser.c @@ -1,14 +1,4 @@ -/* - * yt - A fully featured command line YouTube client - * - * Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> - * SPDX-License-Identifier: GPL-3.0-or-later - * - * This file is part of Yt. - * - * You should have received a copy of the License along with this program. - * If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - */ +/* Automatically @generated by tree-sitter */ #include "tree_sitter/parser.h" @@ -16,168 +6,34 @@ #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -#define LANGUAGE_VERSION 14 -#define STATE_COUNT 39 +#define LANGUAGE_VERSION 15 +#define STATE_COUNT 4 #define LARGE_STATE_COUNT 2 -#define SYMBOL_COUNT 48 +#define SYMBOL_COUNT 3 #define ALIAS_COUNT 0 -#define TOKEN_COUNT 36 +#define TOKEN_COUNT 2 #define EXTERNAL_TOKEN_COUNT 0 #define FIELD_COUNT 0 -#define MAX_ALIAS_SEQUENCE_LENGTH 9 +#define MAX_ALIAS_SEQUENCE_LENGTH 1 +#define MAX_RESERVED_WORD_SET_SIZE 0 #define PRODUCTION_ID_COUNT 1 +#define SUPERTYPE_COUNT 0 -enum ts_symbol_identifiers -{ - anon_sym_LF = 1, - anon_sym_pick = 2, - anon_sym_p = 3, - anon_sym_watch = 4, - anon_sym_w = 5, - anon_sym_watched = 6, - anon_sym_wd = 7, - anon_sym_add = 8, - anon_sym_a = 9, - anon_sym_drop = 10, - anon_sym_d = 11, - anon_sym_url = 12, - anon_sym_u = 13, - aux_sym_flag_token1 = 14, - aux_sym_flag_token2 = 15, - aux_sym_flag_token3 = 16, - aux_sym_flag_token4 = 17, - aux_sym_flag_token5 = 18, - aux_sym_flag_token6 = 19, - aux_sym_flag_token7 = 20, - aux_sym_flag_token8 = 21, - aux_sym_flag_token9 = 22, - aux_sym_flag_token10 = 23, - aux_sym_flag_token11 = 24, - aux_sym_flag_token12 = 25, - sym_id = 26, - aux_sym_title_token1 = 27, - anon_sym_LBRACKNoreleasedate_RBRACK = 28, - aux_sym_date_token1 = 29, - anon_sym_LBRACKNoauthor_RBRACK = 30, - anon_sym_LBRACKNoduration_RBRACK = 31, - aux_sym_duration_token1 = 32, - aux_sym_duration_token2 = 33, - sym_comment = 34, - sym_quote = 35, - sym_source_file = 36, - sym_line = 37, - sym_command = 38, - sym_flag = 39, - sym_title = 40, - sym_date = 41, - sym_author = 42, - sym_duration = 43, - sym_url = 44, - sym__q = 45, - aux_sym_source_file_repeat1 = 46, - aux_sym_line_repeat1 = 47, +enum ts_symbol_identifiers { + anon_sym_hello = 1, + sym_source_file = 2, }; -static const char *const ts_symbol_names[] = { +static const char * const ts_symbol_names[] = { [ts_builtin_sym_end] = "end", - [anon_sym_LF] = "\n", - [anon_sym_pick] = "pick", - [anon_sym_p] = "p", - [anon_sym_watch] = "watch", - [anon_sym_w] = "w", - [anon_sym_watched] = "watched", - [anon_sym_wd] = "wd", - [anon_sym_add] = "add", - [anon_sym_a] = "a", - [anon_sym_drop] = "drop", - [anon_sym_d] = "d", - [anon_sym_url] = "url", - [anon_sym_u] = "u", - [aux_sym_flag_token1] = "flag_token1", - [aux_sym_flag_token2] = "flag_token2", - [aux_sym_flag_token3] = "flag_token3", - [aux_sym_flag_token4] = "flag_token4", - [aux_sym_flag_token5] = "flag_token5", - [aux_sym_flag_token6] = "flag_token6", - [aux_sym_flag_token7] = "flag_token7", - [aux_sym_flag_token8] = "flag_token8", - [aux_sym_flag_token9] = "flag_token9", - [aux_sym_flag_token10] = "flag_token10", - [aux_sym_flag_token11] = "flag_token11", - [aux_sym_flag_token12] = "flag_token12", - [sym_id] = "id", - [aux_sym_title_token1] = "title_token1", - [anon_sym_LBRACKNoreleasedate_RBRACK] = "[No release date]", - [aux_sym_date_token1] = "date_token1", - [anon_sym_LBRACKNoauthor_RBRACK] = "[No author]", - [anon_sym_LBRACKNoduration_RBRACK] = "[No duration]", - [aux_sym_duration_token1] = "duration_token1", - [aux_sym_duration_token2] = "duration_token2", - [sym_comment] = "comment", - [sym_quote] = "quote", + [anon_sym_hello] = "hello", [sym_source_file] = "source_file", - [sym_line] = "line", - [sym_command] = "command", - [sym_flag] = "flag", - [sym_title] = "title", - [sym_date] = "date", - [sym_author] = "author", - [sym_duration] = "duration", - [sym_url] = "url", - [sym__q] = "_q", - [aux_sym_source_file_repeat1] = "source_file_repeat1", - [aux_sym_line_repeat1] = "line_repeat1", }; static const TSSymbol ts_symbol_map[] = { [ts_builtin_sym_end] = ts_builtin_sym_end, - [anon_sym_LF] = anon_sym_LF, - [anon_sym_pick] = anon_sym_pick, - [anon_sym_p] = anon_sym_p, - [anon_sym_watch] = anon_sym_watch, - [anon_sym_w] = anon_sym_w, - [anon_sym_watched] = anon_sym_watched, - [anon_sym_wd] = anon_sym_wd, - [anon_sym_add] = anon_sym_add, - [anon_sym_a] = anon_sym_a, - [anon_sym_drop] = anon_sym_drop, - [anon_sym_d] = anon_sym_d, - [anon_sym_url] = anon_sym_url, - [anon_sym_u] = anon_sym_u, - [aux_sym_flag_token1] = aux_sym_flag_token1, - [aux_sym_flag_token2] = aux_sym_flag_token2, - [aux_sym_flag_token3] = aux_sym_flag_token3, - [aux_sym_flag_token4] = aux_sym_flag_token4, - [aux_sym_flag_token5] = aux_sym_flag_token5, - [aux_sym_flag_token6] = aux_sym_flag_token6, - [aux_sym_flag_token7] = aux_sym_flag_token7, - [aux_sym_flag_token8] = aux_sym_flag_token8, - [aux_sym_flag_token9] = aux_sym_flag_token9, - [aux_sym_flag_token10] = aux_sym_flag_token10, - [aux_sym_flag_token11] = aux_sym_flag_token11, - [aux_sym_flag_token12] = aux_sym_flag_token12, - [sym_id] = sym_id, - [aux_sym_title_token1] = aux_sym_title_token1, - [anon_sym_LBRACKNoreleasedate_RBRACK] = anon_sym_LBRACKNoreleasedate_RBRACK, - [aux_sym_date_token1] = aux_sym_date_token1, - [anon_sym_LBRACKNoauthor_RBRACK] = anon_sym_LBRACKNoauthor_RBRACK, - [anon_sym_LBRACKNoduration_RBRACK] = anon_sym_LBRACKNoduration_RBRACK, - [aux_sym_duration_token1] = aux_sym_duration_token1, - [aux_sym_duration_token2] = aux_sym_duration_token2, - [sym_comment] = sym_comment, - [sym_quote] = sym_quote, + [anon_sym_hello] = anon_sym_hello, [sym_source_file] = sym_source_file, - [sym_line] = sym_line, - [sym_command] = sym_command, - [sym_flag] = sym_flag, - [sym_title] = sym_title, - [sym_date] = sym_date, - [sym_author] = sym_author, - [sym_duration] = sym_duration, - [sym_url] = sym_url, - [sym__q] = sym__q, - [aux_sym_source_file_repeat1] = aux_sym_source_file_repeat1, - [aux_sym_line_repeat1] = aux_sym_line_repeat1, }; static const TSSymbolMetadata ts_symbol_metadata[] = { @@ -185,1580 +41,150 @@ static const TSSymbolMetadata ts_symbol_metadata[] = { .visible = false, .named = true, }, - [anon_sym_LF] = { + [anon_sym_hello] = { .visible = true, .named = false, }, - [anon_sym_pick] = { - .visible = true, - .named = false, - }, - [anon_sym_p] = { - .visible = true, - .named = false, - }, - [anon_sym_watch] = { - .visible = true, - .named = false, - }, - [anon_sym_w] = { - .visible = true, - .named = false, - }, - [anon_sym_watched] = { - .visible = true, - .named = false, - }, - [anon_sym_wd] = { - .visible = true, - .named = false, - }, - [anon_sym_add] = { - .visible = true, - .named = false, - }, - [anon_sym_a] = { - .visible = true, - .named = false, - }, - [anon_sym_drop] = { - .visible = true, - .named = false, - }, - [anon_sym_d] = { - .visible = true, - .named = false, - }, - [anon_sym_url] = { - .visible = true, - .named = false, - }, - [anon_sym_u] = { - .visible = true, - .named = false, - }, - [aux_sym_flag_token1] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token2] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token3] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token4] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token5] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token6] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token7] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token8] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token9] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token10] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token11] = { - .visible = false, - .named = false, - }, - [aux_sym_flag_token12] = { - .visible = false, - .named = false, - }, - [sym_id] = { - .visible = true, - .named = true, - }, - [aux_sym_title_token1] = { - .visible = false, - .named = false, - }, - [anon_sym_LBRACKNoreleasedate_RBRACK] = { - .visible = true, - .named = false, - }, - [aux_sym_date_token1] = { - .visible = false, - .named = false, - }, - [anon_sym_LBRACKNoauthor_RBRACK] = { - .visible = true, - .named = false, - }, - [anon_sym_LBRACKNoduration_RBRACK] = { - .visible = true, - .named = false, - }, - [aux_sym_duration_token1] = { - .visible = false, - .named = false, - }, - [aux_sym_duration_token2] = { - .visible = false, - .named = false, - }, - [sym_comment] = { - .visible = true, - .named = true, - }, - [sym_quote] = { - .visible = true, - .named = true, - }, [sym_source_file] = { .visible = true, .named = true, }, - [sym_line] = { - .visible = true, - .named = true, - }, - [sym_command] = { - .visible = true, - .named = true, - }, - [sym_flag] = { - .visible = true, - .named = true, - }, - [sym_title] = { - .visible = true, - .named = true, - }, - [sym_date] = { - .visible = true, - .named = true, - }, - [sym_author] = { - .visible = true, - .named = true, - }, - [sym_duration] = { - .visible = true, - .named = true, - }, - [sym_url] = { - .visible = true, - .named = true, - }, - [sym__q] = { - .visible = false, - .named = true, - }, - [aux_sym_source_file_repeat1] = { - .visible = false, - .named = false, - }, - [aux_sym_line_repeat1] = { - .visible = false, - .named = false, - }, }; -static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT] - [MAX_ALIAS_SEQUENCE_LENGTH] - = { - [0] = { 0 }, - }; +static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT][MAX_ALIAS_SEQUENCE_LENGTH] = { + [0] = {0}, +}; static const uint16_t ts_non_terminal_alias_map[] = { 0, }; static const TSStateId ts_primary_state_ids[STATE_COUNT] = { - [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, - [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, - [14] = 14, [15] = 15, [16] = 16, [17] = 17, [18] = 18, [19] = 19, [20] = 20, - [21] = 21, [22] = 22, [23] = 23, [24] = 24, [25] = 25, [26] = 26, [27] = 27, - [28] = 28, [29] = 29, [30] = 30, [31] = 31, [32] = 32, [33] = 33, [34] = 34, - [35] = 35, [36] = 36, [37] = 37, [38] = 38, + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 3, }; -static bool -ts_lex (TSLexer *lexer, TSStateId state) -{ - START_LEXER (); - eof = lexer->eof (lexer); - switch (state) - { +static bool ts_lex(TSLexer *lexer, TSStateId state) { + START_LEXER(); + eof = lexer->eof(lexer); + switch (state) { case 0: - if (eof) - ADVANCE (78); - ADVANCE_MAP ('"', 134, '#', 133, '-', 21, '[', 24, 'a', 87, 'd', 89, 'p', - 81, 'u', 91, 'w', 83, ); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - SKIP (0); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (44); - END_STATE (); + if (eof) ADVANCE(5); + if (lookahead == 'h') ADVANCE(1); + if (('\t' <= lookahead && lookahead <= '\r') || + lookahead == ' ') SKIP(0); + END_STATE(); case 1: - if (lookahead == '\n') - ADVANCE (79); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - SKIP (1); - END_STATE (); + if (lookahead == 'e') ADVANCE(3); + END_STATE(); case 2: - if (lookahead == ' ') - ADVANCE (8); - if (lookahead == '=') - ADVANCE (9); - END_STATE (); + if (lookahead == 'l') ADVANCE(4); + END_STATE(); case 3: - if (lookahead == ' ') - ADVANCE (70); - END_STATE (); + if (lookahead == 'l') ADVANCE(2); + END_STATE(); case 4: - if (lookahead == ' ') - ADVANCE (29); - END_STATE (); + if (lookahead == 'o') ADVANCE(6); + END_STATE(); case 5: - if (lookahead == ' ') - ADVANCE (71); - END_STATE (); + ACCEPT_TOKEN(ts_builtin_sym_end); + END_STATE(); case 6: - if (lookahead == ' ') - ADVANCE (37); - END_STATE (); - case 7: - if (lookahead == ' ') - ADVANCE (10); - if (lookahead == '=') - ADVANCE (11); - if (lookahead == '-' || ('0' <= lookahead && lookahead <= '9') - || ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (7); - END_STATE (); - case 8: - if (lookahead == '"') - ADVANCE (92); - if (lookahead == '\'') - ADVANCE (93); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (94); - END_STATE (); - case 9: - if (lookahead == '"') - ADVANCE (97); - if (lookahead == '\'') - ADVANCE (98); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (99); - END_STATE (); - case 10: - if (lookahead == '"') - ADVANCE (102); - if (lookahead == '\'') - ADVANCE (103); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (104); - END_STATE (); - case 11: - if (lookahead == '"') - ADVANCE (107); - if (lookahead == '\'') - ADVANCE (108); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (109); - END_STATE (); - case 12: - if (lookahead == '"') - ADVANCE (96); - if (lookahead != 0) - ADVANCE (12); - END_STATE (); - case 13: - if (lookahead == '"') - ADVANCE (101); - if (lookahead != 0) - ADVANCE (13); - END_STATE (); - case 14: - if (lookahead == '"') - ADVANCE (106); - if (lookahead != 0) - ADVANCE (14); - END_STATE (); - case 15: - if (lookahead == '"') - ADVANCE (111); - if (lookahead != 0) - ADVANCE (15); - END_STATE (); - case 16: - if (lookahead == '\'') - ADVANCE (95); - if (lookahead != 0) - ADVANCE (16); - END_STATE (); - case 17: - if (lookahead == '\'') - ADVANCE (100); - if (lookahead != 0) - ADVANCE (17); - END_STATE (); - case 18: - if (lookahead == '\'') - ADVANCE (105); - if (lookahead != 0) - ADVANCE (18); - END_STATE (); - case 19: - if (lookahead == '\'') - ADVANCE (110); - if (lookahead != 0) - ADVANCE (19); - END_STATE (); - case 20: - if (lookahead == '-') - ADVANCE (21); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - SKIP (20); - if (('0' <= lookahead && lookahead <= '9') - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (112); - END_STATE (); - case 21: - if (lookahead == '-') - ADVANCE (76); - if (('0' <= lookahead && lookahead <= '9') - || ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (2); - END_STATE (); - case 22: - if (lookahead == '-') - ADVANCE (74); - if (lookahead == 'h') - ADVANCE (3); - if (lookahead == 'm') - ADVANCE (5); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (45); - END_STATE (); - case 23: - if (lookahead == '-') - ADVANCE (75); - END_STATE (); - case 24: - if (lookahead == 'N') - ADVANCE (56); - END_STATE (); - case 25: - if (lookahead == '[') - ADVANCE (114); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (115); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 26: - if (lookahead == ']') - ADVANCE (128); - END_STATE (); - case 27: - if (lookahead == ']') - ADVANCE (130); - END_STATE (); - case 28: - if (lookahead == ']') - ADVANCE (126); - END_STATE (); - case 29: - if (lookahead == 'a') - ADVANCE (68); - if (lookahead == 'd') - ADVANCE (67); - if (lookahead == 'r') - ADVANCE (38); - END_STATE (); - case 30: - if (lookahead == 'a') - ADVANCE (62); - END_STATE (); - case 31: - if (lookahead == 'a') - ADVANCE (63); - END_STATE (); - case 32: - if (lookahead == 'a') - ADVANCE (66); - END_STATE (); - case 33: - if (lookahead == 'c') - ADVANCE (49); - END_STATE (); - case 34: - if (lookahead == 'c') - ADVANCE (46); - END_STATE (); - case 35: - if (lookahead == 'd') - ADVANCE (86); - END_STATE (); - case 36: - if (lookahead == 'd') - ADVANCE (84); - END_STATE (); - case 37: - if (lookahead == 'd') - ADVANCE (32); - END_STATE (); - case 38: - if (lookahead == 'e') - ADVANCE (51); - END_STATE (); - case 39: - if (lookahead == 'e') - ADVANCE (30); - END_STATE (); - case 40: - if (lookahead == 'e') - ADVANCE (6); - END_STATE (); - case 41: - if (lookahead == 'e') - ADVANCE (28); - END_STATE (); - case 42: - if (lookahead == 'h') - ADVANCE (3); - if (lookahead == 'm') - ADVANCE (5); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (22); - END_STATE (); - case 43: - if (lookahead == 'h') - ADVANCE (3); - if (lookahead == 'm') - ADVANCE (5); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (42); - END_STATE (); - case 44: - if (lookahead == 'h') - ADVANCE (3); - if (lookahead == 'm') - ADVANCE (5); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (43); - END_STATE (); - case 45: - if (lookahead == 'h') - ADVANCE (3); - if (lookahead == 'm') - ADVANCE (5); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (45); - END_STATE (); - case 46: - if (lookahead == 'h') - ADVANCE (82); - END_STATE (); - case 47: - if (lookahead == 'h') - ADVANCE (57); - END_STATE (); - case 48: - if (lookahead == 'i') - ADVANCE (55); - END_STATE (); - case 49: - if (lookahead == 'k') - ADVANCE (80); - END_STATE (); - case 50: - if (lookahead == 'l') - ADVANCE (90); - END_STATE (); - case 51: - if (lookahead == 'l') - ADVANCE (39); - END_STATE (); - case 52: - if (lookahead == 'm') - ADVANCE (132); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (52); - END_STATE (); - case 53: - if (lookahead == 'n') - ADVANCE (27); - END_STATE (); - case 54: - if (lookahead == 'o') - ADVANCE (58); - END_STATE (); - case 55: - if (lookahead == 'o') - ADVANCE (53); - END_STATE (); - case 56: - if (lookahead == 'o') - ADVANCE (4); - END_STATE (); - case 57: - if (lookahead == 'o') - ADVANCE (60); - END_STATE (); - case 58: - if (lookahead == 'p') - ADVANCE (88); - END_STATE (); - case 59: - if (lookahead == 'r') - ADVANCE (31); - END_STATE (); - case 60: - if (lookahead == 'r') - ADVANCE (26); - END_STATE (); - case 61: - if (lookahead == 's') - ADVANCE (131); - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (61); - END_STATE (); - case 62: - if (lookahead == 's') - ADVANCE (40); - END_STATE (); - case 63: - if (lookahead == 't') - ADVANCE (48); - END_STATE (); - case 64: - if (lookahead == 't') - ADVANCE (34); - END_STATE (); - case 65: - if (lookahead == 't') - ADVANCE (47); - END_STATE (); - case 66: - if (lookahead == 't') - ADVANCE (41); - END_STATE (); - case 67: - if (lookahead == 'u') - ADVANCE (59); - END_STATE (); - case 68: - if (lookahead == 'u') - ADVANCE (65); - END_STATE (); - case 69: - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (124); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 70: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (52); - END_STATE (); - case 71: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (61); - END_STATE (); - case 72: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (23); - END_STATE (); - case 73: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (127); - END_STATE (); - case 74: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (72); - END_STATE (); - case 75: - if (('0' <= lookahead && lookahead <= '9')) - ADVANCE (73); - END_STATE (); - case 76: - if (('0' <= lookahead && lookahead <= '9') - || ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (77); - END_STATE (); - case 77: - if (lookahead == '-' || ('0' <= lookahead && lookahead <= '9') - || ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (7); - END_STATE (); - case 78: - ACCEPT_TOKEN (ts_builtin_sym_end); - END_STATE (); - case 79: - ACCEPT_TOKEN (anon_sym_LF); - if (lookahead == '\n') - ADVANCE (79); - END_STATE (); - case 80: - ACCEPT_TOKEN (anon_sym_pick); - END_STATE (); - case 81: - ACCEPT_TOKEN (anon_sym_p); - if (lookahead == 'i') - ADVANCE (33); - END_STATE (); - case 82: - ACCEPT_TOKEN (anon_sym_watch); - if (lookahead == 'e') - ADVANCE (36); - END_STATE (); - case 83: - ACCEPT_TOKEN (anon_sym_w); - if (lookahead == 'a') - ADVANCE (64); - if (lookahead == 'd') - ADVANCE (85); - END_STATE (); - case 84: - ACCEPT_TOKEN (anon_sym_watched); - END_STATE (); - case 85: - ACCEPT_TOKEN (anon_sym_wd); - END_STATE (); - case 86: - ACCEPT_TOKEN (anon_sym_add); - END_STATE (); - case 87: - ACCEPT_TOKEN (anon_sym_a); - if (lookahead == 'd') - ADVANCE (35); - END_STATE (); - case 88: - ACCEPT_TOKEN (anon_sym_drop); - END_STATE (); - case 89: - ACCEPT_TOKEN (anon_sym_d); - if (lookahead == 'r') - ADVANCE (54); - END_STATE (); - case 90: - ACCEPT_TOKEN (anon_sym_url); - END_STATE (); - case 91: - ACCEPT_TOKEN (anon_sym_u); - if (lookahead == 'r') - ADVANCE (50); - END_STATE (); - case 92: - ACCEPT_TOKEN (aux_sym_flag_token1); - if (lookahead == '"') - ADVANCE (94); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (12); - if (lookahead != 0) - ADVANCE (92); - END_STATE (); - case 93: - ACCEPT_TOKEN (aux_sym_flag_token1); - if (lookahead == '\'') - ADVANCE (94); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (16); - if (lookahead != 0) - ADVANCE (93); - END_STATE (); - case 94: - ACCEPT_TOKEN (aux_sym_flag_token1); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (94); - END_STATE (); - case 95: - ACCEPT_TOKEN (aux_sym_flag_token2); - END_STATE (); - case 96: - ACCEPT_TOKEN (aux_sym_flag_token3); - END_STATE (); - case 97: - ACCEPT_TOKEN (aux_sym_flag_token4); - if (lookahead == '"') - ADVANCE (99); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (13); - if (lookahead != 0) - ADVANCE (97); - END_STATE (); - case 98: - ACCEPT_TOKEN (aux_sym_flag_token4); - if (lookahead == '\'') - ADVANCE (99); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (17); - if (lookahead != 0) - ADVANCE (98); - END_STATE (); - case 99: - ACCEPT_TOKEN (aux_sym_flag_token4); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (99); - END_STATE (); - case 100: - ACCEPT_TOKEN (aux_sym_flag_token5); - END_STATE (); - case 101: - ACCEPT_TOKEN (aux_sym_flag_token6); - END_STATE (); - case 102: - ACCEPT_TOKEN (aux_sym_flag_token7); - if (lookahead == '"') - ADVANCE (104); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (14); - if (lookahead != 0) - ADVANCE (102); - END_STATE (); - case 103: - ACCEPT_TOKEN (aux_sym_flag_token7); - if (lookahead == '\'') - ADVANCE (104); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (18); - if (lookahead != 0) - ADVANCE (103); - END_STATE (); - case 104: - ACCEPT_TOKEN (aux_sym_flag_token7); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (104); - END_STATE (); - case 105: - ACCEPT_TOKEN (aux_sym_flag_token8); - END_STATE (); - case 106: - ACCEPT_TOKEN (aux_sym_flag_token9); - END_STATE (); - case 107: - ACCEPT_TOKEN (aux_sym_flag_token10); - if (lookahead == '"') - ADVANCE (109); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (15); - if (lookahead != 0) - ADVANCE (107); - END_STATE (); - case 108: - ACCEPT_TOKEN (aux_sym_flag_token10); - if (lookahead == '\'') - ADVANCE (109); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (19); - if (lookahead != 0) - ADVANCE (108); - END_STATE (); - case 109: - ACCEPT_TOKEN (aux_sym_flag_token10); - if (lookahead != 0 && (lookahead < '\t' || '\r' < lookahead) - && lookahead != ' ') - ADVANCE (109); - END_STATE (); - case 110: - ACCEPT_TOKEN (aux_sym_flag_token11); - END_STATE (); - case 111: - ACCEPT_TOKEN (aux_sym_flag_token12); - END_STATE (); - case 112: - ACCEPT_TOKEN (sym_id); - if (('0' <= lookahead && lookahead <= '9') - || ('a' <= lookahead && lookahead <= 'z')) - ADVANCE (112); - END_STATE (); - case 113: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == ' ') - ADVANCE (117); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 114: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'N') - ADVANCE (119); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 115: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == '[') - ADVANCE (114); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (115); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 116: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == ']') - ADVANCE (129); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 117: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'a') - ADVANCE (123); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 118: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'h') - ADVANCE (120); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 119: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'o') - ADVANCE (113); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 120: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'o') - ADVANCE (121); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 121: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'r') - ADVANCE (116); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 122: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 't') - ADVANCE (118); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 123: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead == 'u') - ADVANCE (122); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 124: - ACCEPT_TOKEN (aux_sym_title_token1); - if (('\t' <= lookahead && lookahead <= '\r') || lookahead == ' ') - ADVANCE (124); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 125: - ACCEPT_TOKEN (aux_sym_title_token1); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 126: - ACCEPT_TOKEN (anon_sym_LBRACKNoreleasedate_RBRACK); - END_STATE (); - case 127: - ACCEPT_TOKEN (aux_sym_date_token1); - END_STATE (); - case 128: - ACCEPT_TOKEN (anon_sym_LBRACKNoauthor_RBRACK); - END_STATE (); - case 129: - ACCEPT_TOKEN (anon_sym_LBRACKNoauthor_RBRACK); - if (lookahead != 0 && lookahead != '"') - ADVANCE (125); - END_STATE (); - case 130: - ACCEPT_TOKEN (anon_sym_LBRACKNoduration_RBRACK); - END_STATE (); - case 131: - ACCEPT_TOKEN (aux_sym_duration_token1); - END_STATE (); - case 132: - ACCEPT_TOKEN (aux_sym_duration_token2); - END_STATE (); - case 133: - ACCEPT_TOKEN (sym_comment); - if (lookahead != 0 && lookahead != '\n') - ADVANCE (133); - END_STATE (); - case 134: - ACCEPT_TOKEN (sym_quote); - END_STATE (); + ACCEPT_TOKEN(anon_sym_hello); + END_STATE(); default: return false; - } + } } -static const TSLexMode ts_lex_modes[STATE_COUNT] = { - [0] = { .lex_state = 0 }, [1] = { .lex_state = 0 }, - [2] = { .lex_state = 0 }, [3] = { .lex_state = 0 }, - [4] = { .lex_state = 20 }, [5] = { .lex_state = 20 }, - [6] = { .lex_state = 20 }, [7] = { .lex_state = 0 }, - [8] = { .lex_state = 0 }, [9] = { .lex_state = 20 }, - [10] = { .lex_state = 20 }, [11] = { .lex_state = 0 }, - [12] = { .lex_state = 0 }, [13] = { .lex_state = 0 }, - [14] = { .lex_state = 0 }, [15] = { .lex_state = 0 }, - [16] = { .lex_state = 0 }, [17] = { .lex_state = 0 }, - [18] = { .lex_state = 0 }, [19] = { .lex_state = 0 }, - [20] = { .lex_state = 0 }, [21] = { .lex_state = 0 }, - [22] = { .lex_state = 0 }, [23] = { .lex_state = 25 }, - [24] = { .lex_state = 0 }, [25] = { .lex_state = 0 }, - [26] = { .lex_state = 0 }, [27] = { .lex_state = 0 }, - [28] = { .lex_state = 0 }, [29] = { .lex_state = 69 }, - [30] = { .lex_state = 0 }, [31] = { .lex_state = 0 }, - [32] = { .lex_state = 0 }, [33] = { .lex_state = 0 }, - [34] = { .lex_state = 1 }, [35] = { .lex_state = 0 }, - [36] = { .lex_state = 1 }, [37] = { .lex_state = 1 }, - [38] = { .lex_state = 69 }, +static const TSLexerMode ts_lex_modes[STATE_COUNT] = { + [0] = {.lex_state = 0}, + [1] = {.lex_state = 0}, + [2] = {.lex_state = 0}, + [3] = {.lex_state = 0}, }; static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { - [0] = { + [STATE(0)] = { [ts_builtin_sym_end] = ACTIONS(1), - [anon_sym_pick] = ACTIONS(1), - [anon_sym_p] = ACTIONS(1), - [anon_sym_watch] = ACTIONS(1), - [anon_sym_w] = ACTIONS(1), - [anon_sym_watched] = ACTIONS(1), - [anon_sym_wd] = ACTIONS(1), - [anon_sym_add] = ACTIONS(1), - [anon_sym_a] = ACTIONS(1), - [anon_sym_drop] = ACTIONS(1), - [anon_sym_d] = ACTIONS(1), - [anon_sym_url] = ACTIONS(1), - [anon_sym_u] = ACTIONS(1), - [aux_sym_flag_token1] = ACTIONS(1), - [aux_sym_flag_token2] = ACTIONS(1), - [aux_sym_flag_token3] = ACTIONS(1), - [aux_sym_flag_token4] = ACTIONS(1), - [aux_sym_flag_token5] = ACTIONS(1), - [aux_sym_flag_token6] = ACTIONS(1), - [aux_sym_flag_token7] = ACTIONS(1), - [aux_sym_flag_token8] = ACTIONS(1), - [aux_sym_flag_token9] = ACTIONS(1), - [aux_sym_flag_token10] = ACTIONS(1), - [aux_sym_flag_token11] = ACTIONS(1), - [aux_sym_flag_token12] = ACTIONS(1), - [anon_sym_LBRACKNoreleasedate_RBRACK] = ACTIONS(1), - [aux_sym_date_token1] = ACTIONS(1), - [anon_sym_LBRACKNoauthor_RBRACK] = ACTIONS(1), - [anon_sym_LBRACKNoduration_RBRACK] = ACTIONS(1), - [aux_sym_duration_token1] = ACTIONS(1), - [aux_sym_duration_token2] = ACTIONS(1), - [sym_comment] = ACTIONS(1), - [sym_quote] = ACTIONS(1), + [anon_sym_hello] = ACTIONS(1), }, - [1] = { - [sym_source_file] = STATE(30), - [sym_line] = STATE(3), - [sym_command] = STATE(4), - [aux_sym_source_file_repeat1] = STATE(3), - [ts_builtin_sym_end] = ACTIONS(3), - [anon_sym_pick] = ACTIONS(5), - [anon_sym_p] = ACTIONS(7), - [anon_sym_watch] = ACTIONS(7), - [anon_sym_w] = ACTIONS(7), - [anon_sym_watched] = ACTIONS(5), - [anon_sym_wd] = ACTIONS(5), - [anon_sym_add] = ACTIONS(5), - [anon_sym_a] = ACTIONS(7), - [anon_sym_drop] = ACTIONS(5), - [anon_sym_d] = ACTIONS(7), - [anon_sym_url] = ACTIONS(5), - [anon_sym_u] = ACTIONS(7), - [sym_comment] = ACTIONS(9), + [STATE(1)] = { + [sym_source_file] = STATE(3), + [anon_sym_hello] = ACTIONS(3), }, }; static const uint16_t ts_small_parse_table[] = { - [0] = 6, - ACTIONS (11), - 1, - ts_builtin_sym_end, - ACTIONS (19), - 1, - sym_comment, - STATE (4), - 1, - sym_command, - STATE (2), - 2, - sym_line, - aux_sym_source_file_repeat1, - ACTIONS (13), - 6, - anon_sym_pick, - anon_sym_watched, - anon_sym_wd, - anon_sym_add, - anon_sym_drop, - anon_sym_url, - ACTIONS (16), - 6, - anon_sym_p, - anon_sym_watch, - anon_sym_w, - anon_sym_a, - anon_sym_d, - anon_sym_u, - [30] = 6, - ACTIONS (22), - 1, - ts_builtin_sym_end, - ACTIONS (24), - 1, - sym_comment, - STATE (4), - 1, - sym_command, - STATE (2), - 2, - sym_line, - aux_sym_source_file_repeat1, - ACTIONS (5), - 6, - anon_sym_pick, - anon_sym_watched, - anon_sym_wd, - anon_sym_add, - anon_sym_drop, - anon_sym_url, - ACTIONS (7), - 6, - anon_sym_p, - anon_sym_watch, - anon_sym_w, - anon_sym_a, - anon_sym_d, - anon_sym_u, - [60] = 3, - ACTIONS (28), - 1, - sym_id, - STATE (5), - 2, - sym_flag, - aux_sym_line_repeat1, - ACTIONS (26), - 12, - aux_sym_flag_token1, - aux_sym_flag_token2, - aux_sym_flag_token3, - aux_sym_flag_token4, - aux_sym_flag_token5, - aux_sym_flag_token6, - aux_sym_flag_token7, - aux_sym_flag_token8, - aux_sym_flag_token9, - aux_sym_flag_token10, - aux_sym_flag_token11, - aux_sym_flag_token12, - [82] = 3, - ACTIONS (30), - 1, - sym_id, - STATE (6), - 2, - sym_flag, - aux_sym_line_repeat1, - ACTIONS (26), - 12, - aux_sym_flag_token1, - aux_sym_flag_token2, - aux_sym_flag_token3, - aux_sym_flag_token4, - aux_sym_flag_token5, - aux_sym_flag_token6, - aux_sym_flag_token7, - aux_sym_flag_token8, - aux_sym_flag_token9, - aux_sym_flag_token10, - aux_sym_flag_token11, - aux_sym_flag_token12, - [104] = 3, - ACTIONS (35), - 1, - sym_id, - STATE (6), - 2, - sym_flag, - aux_sym_line_repeat1, - ACTIONS (32), - 12, - aux_sym_flag_token1, - aux_sym_flag_token2, - aux_sym_flag_token3, - aux_sym_flag_token4, - aux_sym_flag_token5, - aux_sym_flag_token6, - aux_sym_flag_token7, - aux_sym_flag_token8, - aux_sym_flag_token9, - aux_sym_flag_token10, - aux_sym_flag_token11, - aux_sym_flag_token12, - [126] = 2, - ACTIONS (39), - 6, - anon_sym_p, - anon_sym_watch, - anon_sym_w, - anon_sym_a, - anon_sym_d, - anon_sym_u, - ACTIONS (37), - 8, - ts_builtin_sym_end, - anon_sym_pick, - anon_sym_watched, - anon_sym_wd, - anon_sym_add, - anon_sym_drop, - anon_sym_url, - sym_comment, - [145] = 2, - ACTIONS (43), - 6, - anon_sym_p, - anon_sym_watch, - anon_sym_w, - anon_sym_a, - anon_sym_d, - anon_sym_u, - ACTIONS (41), - 8, - ts_builtin_sym_end, - anon_sym_pick, - anon_sym_watched, - anon_sym_wd, - anon_sym_add, - anon_sym_drop, - anon_sym_url, - sym_comment, - [164] = 2, - ACTIONS (47), - 1, - sym_id, - ACTIONS (45), - 12, - aux_sym_flag_token1, - aux_sym_flag_token2, - aux_sym_flag_token3, - aux_sym_flag_token4, - aux_sym_flag_token5, - aux_sym_flag_token6, - aux_sym_flag_token7, - aux_sym_flag_token8, - aux_sym_flag_token9, - aux_sym_flag_token10, - aux_sym_flag_token11, - aux_sym_flag_token12, - [182] = 2, - ACTIONS (51), - 1, - sym_id, - ACTIONS (49), - 12, - aux_sym_flag_token1, - aux_sym_flag_token2, - aux_sym_flag_token3, - aux_sym_flag_token4, - aux_sym_flag_token5, - aux_sym_flag_token6, - aux_sym_flag_token7, - aux_sym_flag_token8, - aux_sym_flag_token9, - aux_sym_flag_token10, - aux_sym_flag_token11, - aux_sym_flag_token12, - [200] = 3, - ACTIONS (53), - 1, - sym_quote, - STATE (12), - 1, - sym_title, - STATE (38), - 1, - sym__q, - [210] = 3, - ACTIONS (55), - 1, - sym_quote, - STATE (14), - 1, - sym_date, - STATE (24), - 1, - sym__q, - [220] = 3, - ACTIONS (53), - 1, - sym_quote, - STATE (15), - 1, - sym_title, - STATE (38), - 1, - sym__q, - [230] = 3, - ACTIONS (57), - 1, - sym_quote, - STATE (16), - 1, - sym_author, - STATE (23), - 1, - sym__q, - [240] = 3, - ACTIONS (55), - 1, - sym_quote, - STATE (17), - 1, - sym_date, - STATE (24), - 1, - sym__q, - [250] = 3, - ACTIONS (59), - 1, - sym_quote, - STATE (18), - 1, - sym_duration, - STATE (19), - 1, - sym__q, - [260] = 3, - ACTIONS (57), - 1, - sym_quote, - STATE (20), - 1, - sym_author, - STATE (23), - 1, - sym__q, - [270] = 3, - ACTIONS (61), - 1, - sym_quote, - STATE (29), - 1, - sym__q, - STATE (34), - 1, - sym_url, - [280] = 1, - ACTIONS (63), - 3, - anon_sym_LBRACKNoduration_RBRACK, - aux_sym_duration_token1, - aux_sym_duration_token2, - [286] = 3, - ACTIONS (59), - 1, - sym_quote, - STATE (19), - 1, - sym__q, - STATE (21), - 1, - sym_duration, - [296] = 3, - ACTIONS (61), - 1, - sym_quote, - STATE (29), - 1, - sym__q, - STATE (36), - 1, - sym_url, - [306] = 2, - ACTIONS (65), - 1, - sym_quote, - STATE (33), - 1, - sym__q, - [313] = 1, - ACTIONS (67), - 2, - aux_sym_title_token1, - anon_sym_LBRACKNoauthor_RBRACK, - [318] = 1, - ACTIONS (69), - 2, - anon_sym_LBRACKNoreleasedate_RBRACK, - aux_sym_date_token1, - [323] = 2, - ACTIONS (71), - 1, - sym_quote, - STATE (31), - 1, - sym__q, - [330] = 2, - ACTIONS (73), - 1, - sym_quote, - STATE (35), - 1, - sym__q, - [337] = 2, - ACTIONS (75), - 1, - sym_quote, - STATE (32), - 1, - sym__q, - [344] = 2, - ACTIONS (77), - 1, - sym_quote, - STATE (37), - 1, - sym__q, - [351] = 1, - ACTIONS (79), - 1, - aux_sym_title_token1, - [355] = 1, - ACTIONS (81), - 1, - ts_builtin_sym_end, - [359] = 1, - ACTIONS (83), - 1, - sym_quote, - [363] = 1, - ACTIONS (85), - 1, - sym_quote, - [367] = 1, - ACTIONS (87), - 1, - sym_quote, - [371] = 1, - ACTIONS (89), - 1, - anon_sym_LF, - [375] = 1, - ACTIONS (91), - 1, - sym_quote, - [379] = 1, - ACTIONS (93), - 1, - anon_sym_LF, - [383] = 1, - ACTIONS (95), - 1, - anon_sym_LF, - [387] = 1, - ACTIONS (97), - 1, - aux_sym_title_token1, + [0] = 1, + ACTIONS(5), 1, + ts_builtin_sym_end, + [4] = 1, + ACTIONS(7), 1, + ts_builtin_sym_end, }; static const uint32_t ts_small_parse_table_map[] = { - [SMALL_STATE (2)] = 0, [SMALL_STATE (3)] = 30, [SMALL_STATE (4)] = 60, - [SMALL_STATE (5)] = 82, [SMALL_STATE (6)] = 104, [SMALL_STATE (7)] = 126, - [SMALL_STATE (8)] = 145, [SMALL_STATE (9)] = 164, [SMALL_STATE (10)] = 182, - [SMALL_STATE (11)] = 200, [SMALL_STATE (12)] = 210, [SMALL_STATE (13)] = 220, - [SMALL_STATE (14)] = 230, [SMALL_STATE (15)] = 240, [SMALL_STATE (16)] = 250, - [SMALL_STATE (17)] = 260, [SMALL_STATE (18)] = 270, [SMALL_STATE (19)] = 280, - [SMALL_STATE (20)] = 286, [SMALL_STATE (21)] = 296, [SMALL_STATE (22)] = 306, - [SMALL_STATE (23)] = 313, [SMALL_STATE (24)] = 318, [SMALL_STATE (25)] = 323, - [SMALL_STATE (26)] = 330, [SMALL_STATE (27)] = 337, [SMALL_STATE (28)] = 344, - [SMALL_STATE (29)] = 351, [SMALL_STATE (30)] = 355, [SMALL_STATE (31)] = 359, - [SMALL_STATE (32)] = 363, [SMALL_STATE (33)] = 367, [SMALL_STATE (34)] = 371, - [SMALL_STATE (35)] = 375, [SMALL_STATE (36)] = 379, [SMALL_STATE (37)] = 383, - [SMALL_STATE (38)] = 387, + [SMALL_STATE(2)] = 0, + [SMALL_STATE(3)] = 4, }; static const TSParseActionEntry ts_parse_actions[] = { - [0] = { .entry = { .count = 0, .reusable = false } }, - [1] = { .entry = { .count = 1, .reusable = false } }, - RECOVER (), - [3] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_source_file, 0, 0, 0), - [5] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (10), - [7] = { .entry = { .count = 1, .reusable = false } }, - SHIFT (10), - [9] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (3), - [11] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2, 0, 0), - [13] = { .entry = { .count = 2, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2, 0, 0), - SHIFT_REPEAT (10), - [16] = { .entry = { .count = 2, .reusable = false } }, - REDUCE (aux_sym_source_file_repeat1, 2, 0, 0), - SHIFT_REPEAT (10), - [19] = { .entry = { .count = 2, .reusable = true } }, - REDUCE (aux_sym_source_file_repeat1, 2, 0, 0), - SHIFT_REPEAT (2), - [22] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_source_file, 1, 0, 0), - [24] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (2), - [26] = { .entry = { .count = 1, .reusable = false } }, - SHIFT (9), - [28] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (11), - [30] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (13), - [32] = { .entry = { .count = 2, .reusable = false } }, - REDUCE (aux_sym_line_repeat1, 2, 0, 0), - SHIFT_REPEAT (9), - [35] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (aux_sym_line_repeat1, 2, 0, 0), - [37] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_line, 8, 0, 0), - [39] = { .entry = { .count = 1, .reusable = false } }, - REDUCE (sym_line, 8, 0, 0), - [41] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_line, 9, 0, 0), - [43] = { .entry = { .count = 1, .reusable = false } }, - REDUCE (sym_line, 9, 0, 0), - [45] = { .entry = { .count = 1, .reusable = false } }, - REDUCE (sym_flag, 1, 0, 0), - [47] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_flag, 1, 0, 0), - [49] = { .entry = { .count = 1, .reusable = false } }, - REDUCE (sym_command, 1, 0, 0), - [51] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_command, 1, 0, 0), - [53] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (38), - [55] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (24), - [57] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (23), - [59] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (19), - [61] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (29), - [63] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (26), - [65] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (33), - [67] = { .entry = { .count = 1, .reusable = false } }, - SHIFT (25), - [69] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (27), - [71] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (31), - [73] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (35), - [75] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (32), - [77] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (37), - [79] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (28), - [81] = { .entry = { .count = 1, .reusable = true } }, - ACCEPT_INPUT (), - [83] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_author, 3, 0, 0), - [85] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_date, 3, 0, 0), - [87] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_title, 3, 0, 0), - [89] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (7), - [91] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_duration, 3, 0, 0), - [93] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (8), - [95] = { .entry = { .count = 1, .reusable = true } }, - REDUCE (sym_url, 3, 0, 0), - [97] = { .entry = { .count = 1, .reusable = true } }, - SHIFT (22), + [0] = {.entry = {.count = 0, .reusable = false}}, + [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), + [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), + [5] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_source_file, 1, 0, 0), + [7] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), }; #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #ifdef TREE_SITTER_HIDE_SYMBOLS #define TS_PUBLIC #elif defined(_WIN32) -#define TS_PUBLIC __declspec (dllexport) +#define TS_PUBLIC __declspec(dllexport) #else -#define TS_PUBLIC __attribute__ ((visibility ("default"))) +#define TS_PUBLIC __attribute__((visibility("default"))) #endif - TS_PUBLIC const TSLanguage * - tree_sitter_yts (void) - { - static const TSLanguage language = { - .version = LANGUAGE_VERSION, - .symbol_count = SYMBOL_COUNT, - .alias_count = ALIAS_COUNT, - .token_count = TOKEN_COUNT, - .external_token_count = EXTERNAL_TOKEN_COUNT, - .state_count = STATE_COUNT, - .large_state_count = LARGE_STATE_COUNT, - .production_id_count = PRODUCTION_ID_COUNT, - .field_count = FIELD_COUNT, - .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, - .parse_table = &ts_parse_table[0][0], - .small_parse_table = ts_small_parse_table, - .small_parse_table_map = ts_small_parse_table_map, - .parse_actions = ts_parse_actions, - .symbol_names = ts_symbol_names, - .symbol_metadata = ts_symbol_metadata, - .public_symbol_map = ts_symbol_map, - .alias_map = ts_non_terminal_alias_map, - .alias_sequences = &ts_alias_sequences[0][0], - .lex_modes = ts_lex_modes, - .lex_fn = ts_lex, - .primary_state_ids = ts_primary_state_ids, - }; - return &language; - } +TS_PUBLIC const TSLanguage *tree_sitter_yts(void) { + static const TSLanguage language = { + .abi_version = LANGUAGE_VERSION, + .symbol_count = SYMBOL_COUNT, + .alias_count = ALIAS_COUNT, + .token_count = TOKEN_COUNT, + .external_token_count = EXTERNAL_TOKEN_COUNT, + .state_count = STATE_COUNT, + .large_state_count = LARGE_STATE_COUNT, + .production_id_count = PRODUCTION_ID_COUNT, + .supertype_count = SUPERTYPE_COUNT, + .field_count = FIELD_COUNT, + .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, + .parse_table = &ts_parse_table[0][0], + .small_parse_table = ts_small_parse_table, + .small_parse_table_map = ts_small_parse_table_map, + .parse_actions = ts_parse_actions, + .symbol_names = ts_symbol_names, + .symbol_metadata = ts_symbol_metadata, + .public_symbol_map = ts_symbol_map, + .alias_map = ts_non_terminal_alias_map, + .alias_sequences = &ts_alias_sequences[0][0], + .lex_modes = (const void*)ts_lex_modes, + .lex_fn = ts_lex, + .primary_state_ids = ts_primary_state_ids, + .name = "yts", + .max_reserved_word_set_size = 0, + .metadata = { + .major_version = 0, + .minor_version = 1, + .patch_version = 0, + }, + }; + return &language; +} #ifdef __cplusplus } #endif diff --git a/tree-sitter-yts/src/tree_sitter/alloc.h b/tree-sitter-yts/src/tree_sitter/alloc.h index fcaeaad..1abdd12 100644 --- a/tree-sitter-yts/src/tree_sitter/alloc.h +++ b/tree-sitter-yts/src/tree_sitter/alloc.h @@ -1,21 +1,8 @@ -/* - * yt - A fully featured command line YouTube client - * - * Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> - * SPDX-License-Identifier: GPL-3.0-or-later - * - * This file is part of Yt. - * - * You should have received a copy of the License along with this program. - * If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - */ - #ifndef TREE_SITTER_ALLOC_H_ #define TREE_SITTER_ALLOC_H_ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include <stdbool.h> @@ -25,37 +12,37 @@ extern "C" // Allow clients to override allocation functions #ifdef TREE_SITTER_REUSE_ALLOCATOR - extern void *(*ts_current_malloc) (size_t size); - extern void *(*ts_current_calloc) (size_t count, size_t size); - extern void *(*ts_current_realloc) (void *ptr, size_t size); - extern void (*ts_current_free) (void *ptr); +extern void *(*ts_current_malloc)(size_t size); +extern void *(*ts_current_calloc)(size_t count, size_t size); +extern void *(*ts_current_realloc)(void *ptr, size_t size); +extern void (*ts_current_free)(void *ptr); #ifndef ts_malloc -#define ts_malloc ts_current_malloc +#define ts_malloc ts_current_malloc #endif #ifndef ts_calloc -#define ts_calloc ts_current_calloc +#define ts_calloc ts_current_calloc #endif #ifndef ts_realloc #define ts_realloc ts_current_realloc #endif #ifndef ts_free -#define ts_free ts_current_free +#define ts_free ts_current_free #endif #else #ifndef ts_malloc -#define ts_malloc malloc +#define ts_malloc malloc #endif #ifndef ts_calloc -#define ts_calloc calloc +#define ts_calloc calloc #endif #ifndef ts_realloc #define ts_realloc realloc #endif #ifndef ts_free -#define ts_free free +#define ts_free free #endif #endif diff --git a/tree-sitter-yts/src/tree_sitter/array.h b/tree-sitter-yts/src/tree_sitter/array.h index 576d72e..56fc8cd 100644 --- a/tree-sitter-yts/src/tree_sitter/array.h +++ b/tree-sitter-yts/src/tree_sitter/array.h @@ -1,21 +1,8 @@ -/* - * yt - A fully featured command line YouTube client - * - * Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> - * SPDX-License-Identifier: GPL-3.0-or-later - * - * This file is part of Yt. - * - * You should have received a copy of the License along with this program. - * If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - */ - #ifndef TREE_SITTER_ARRAY_H_ #define TREE_SITTER_ARRAY_H_ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include "./alloc.h" @@ -27,36 +14,37 @@ extern "C" #include <string.h> #ifdef _MSC_VER +#pragma warning(push) #pragma warning(disable : 4101) #elif defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #endif -#define Array(T) \ - struct \ - { \ - T *contents; \ - uint32_t size; \ - uint32_t capacity; \ +#define Array(T) \ + struct { \ + T *contents; \ + uint32_t size; \ + uint32_t capacity; \ } /// Initialize an array. -#define array_init(self) \ +#define array_init(self) \ ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) /// Create an empty array. -#define array_new() { NULL, 0, 0 } +#define array_new() \ + { NULL, 0, 0 } /// Get a pointer to the element at a given `index` in the array. -#define array_get(self, _index) \ - (assert ((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) +#define array_get(self, _index) \ + (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) /// Get a pointer to the first element in the array. -#define array_front(self) array_get (self, 0) +#define array_front(self) array_get(self, 0) /// Get a pointer to the last element in the array. -#define array_back(self) array_get (self, (self)->size - 1) +#define array_back(self) array_get(self, (self)->size - 1) /// Clear the array, setting its size to zero. Note that this does not free any /// memory allocated for the array's contents. @@ -64,69 +52,96 @@ extern "C" /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is /// less than the array's current capacity, this function has no effect. -#define array_reserve(self, new_capacity) \ - _array__reserve ((Array *)(self), array_elem_size (self), new_capacity) +#define array_reserve(self, new_capacity) \ + ((self)->contents = _array__reserve( \ + (void *)(self)->contents, &(self)->capacity, \ + array_elem_size(self), new_capacity) \ + ) /// Free any memory allocated for this array. Note that this does not free any /// memory allocated for the array's contents. -#define array_delete(self) _array__delete ((Array *)(self)) +#define array_delete(self) \ + do { \ + if ((self)->contents) ts_free((self)->contents); \ + (self)->contents = NULL; \ + (self)->size = 0; \ + (self)->capacity = 0; \ + } while (0) /// Push a new `element` onto the end of the array. -#define array_push(self, element) \ - (_array__grow ((Array *)(self), 1, array_elem_size (self)), \ - (self)->contents[(self)->size++] = (element)) +#define array_push(self, element) \ + do { \ + (self)->contents = _array__grow( \ + (void *)(self)->contents, (self)->size, &(self)->capacity, \ + 1, array_elem_size(self) \ + ); \ + (self)->contents[(self)->size++] = (element); \ + } while(0) /// Increase the array's size by `count` elements. /// New elements are zero-initialized. -#define array_grow_by(self, count) \ - do \ - { \ - if ((count) == 0) \ - break; \ - _array__grow ((Array *)(self), count, array_elem_size (self)); \ - memset ((self)->contents + (self)->size, 0, \ - (count) * array_elem_size (self)); \ - (self)->size += (count); \ - } \ - while (0) +#define array_grow_by(self, count) \ + do { \ + if ((count) == 0) break; \ + (self)->contents = _array__grow( \ + (self)->contents, (self)->size, &(self)->capacity, \ + count, array_elem_size(self) \ + ); \ + memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ + (self)->size += (count); \ + } while (0) /// Append all elements from one array to the end of another. -#define array_push_all(self, other) \ - array_extend ((self), (other)->size, (other)->contents) +#define array_push_all(self, other) \ + array_extend((self), (other)->size, (other)->contents) -/// Append `count` elements to the end of the array, reading their values from -/// the `contents` pointer. -#define array_extend(self, count, contents) \ - _array__splice ((Array *)(self), array_elem_size (self), (self)->size, 0, \ - count, contents) +/// Append `count` elements to the end of the array, reading their values from the +/// `contents` pointer. +#define array_extend(self, count, other_contents) \ + (self)->contents = _array__splice( \ + (void*)(self)->contents, &(self)->size, &(self)->capacity, \ + array_elem_size(self), (self)->size, 0, count, other_contents \ + ) -/// Remove `old_count` elements from the array starting at the given `index`. -/// At the same index, insert `new_count` new elements, reading their values -/// from the `new_contents` pointer. -#define array_splice(self, _index, old_count, new_count, new_contents) \ - _array__splice ((Array *)(self), array_elem_size (self), _index, old_count, \ - new_count, new_contents) +/// Remove `old_count` elements from the array starting at the given `index`. At +/// the same index, insert `new_count` new elements, reading their values from the +/// `new_contents` pointer. +#define array_splice(self, _index, old_count, new_count, new_contents) \ + (self)->contents = _array__splice( \ + (void *)(self)->contents, &(self)->size, &(self)->capacity, \ + array_elem_size(self), _index, old_count, new_count, new_contents \ + ) /// Insert one `element` into the array at the given `index`. -#define array_insert(self, _index, element) \ - _array__splice ((Array *)(self), array_elem_size (self), _index, 0, 1, \ - &(element)) +#define array_insert(self, _index, element) \ + (self)->contents = _array__splice( \ + (void *)(self)->contents, &(self)->size, &(self)->capacity, \ + array_elem_size(self), _index, 0, 1, &(element) \ + ) /// Remove one element from the array at the given `index`. -#define array_erase(self, _index) \ - _array__erase ((Array *)(self), array_elem_size (self), _index) +#define array_erase(self, _index) \ + _array__erase((void *)(self)->contents, &(self)->size, array_elem_size(self), _index) /// Pop the last element off the array, returning the element by value. #define array_pop(self) ((self)->contents[--(self)->size]) /// Assign the contents of one array to another, reallocating if necessary. -#define array_assign(self, other) \ - _array__assign ((Array *)(self), (const Array *)(other), \ - array_elem_size (self)) +#define array_assign(self, other) \ + (self)->contents = _array__assign( \ + (void *)(self)->contents, &(self)->size, &(self)->capacity, \ + (const void *)(other)->contents, (other)->size, array_elem_size(self) \ + ) /// Swap one array with another -#define array_swap(self, other) \ - _array__swap ((Array *)(self), (Array *)(other)) +#define array_swap(self, other) \ + do { \ + void *_array_swap_tmp = (void *)(self)->contents; \ + (self)->contents = (other)->contents; \ + (other)->contents = _array_swap_tmp; \ + _array__swap(&(self)->size, &(self)->capacity, \ + &(other)->size, &(other)->capacity); \ + } while (0) /// Get the size of the array contents #define array_elem_size(self) (sizeof *(self)->contents) @@ -139,198 +154,171 @@ extern "C" /// out-parameter is set to true. Otherwise, `index` is set to an index where /// `needle` should be inserted in order to preserve the sorting, and `exists` /// is set to false. -#define array_search_sorted_with(self, compare, needle, _index, _exists) \ - _array__search_sorted (self, 0, compare, , needle, _index, _exists) +#define array_search_sorted_with(self, compare, needle, _index, _exists) \ + _array__search_sorted(self, 0, compare, , needle, _index, _exists) /// Search a sorted array for a given `needle` value, using integer comparisons -/// of a given struct field (specified with a leading dot) to determine the -/// order. +/// of a given struct field (specified with a leading dot) to determine the order. /// /// See also `array_search_sorted_with`. -#define array_search_sorted_by(self, field, needle, _index, _exists) \ - _array__search_sorted (self, 0, _compare_int, field, needle, _index, _exists) +#define array_search_sorted_by(self, field, needle, _index, _exists) \ + _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) /// Insert a given `value` into a sorted array, using the given `compare` /// callback to determine the order. -#define array_insert_sorted_with(self, compare, value) \ - do \ - { \ - unsigned _index, _exists; \ - array_search_sorted_with (self, compare, &(value), &_index, &_exists); \ - if (!_exists) \ - array_insert (self, _index, value); \ - } \ - while (0) +#define array_insert_sorted_with(self, compare, value) \ + do { \ + unsigned _index, _exists; \ + array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ + if (!_exists) array_insert(self, _index, value); \ + } while (0) /// Insert a given `value` into a sorted array, using integer comparisons of /// a given struct field (specified with a leading dot) to determine the order. /// /// See also `array_search_sorted_by`. -#define array_insert_sorted_by(self, field, value) \ - do \ - { \ - unsigned _index, _exists; \ - array_search_sorted_by (self, field, (value)field, &_index, &_exists); \ - if (!_exists) \ - array_insert (self, _index, value); \ - } \ - while (0) - - // Private +#define array_insert_sorted_by(self, field, value) \ + do { \ + unsigned _index, _exists; \ + array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ + if (!_exists) array_insert(self, _index, value); \ + } while (0) - typedef Array (void) Array; +// Private - /// This is not what you're looking for, see `array_delete`. - static inline void - _array__delete (Array *self) - { - if (self->contents) - { - ts_free (self->contents); - self->contents = NULL; - self->size = 0; - self->capacity = 0; - } - } +// Pointers to individual `Array` fields (rather than the entire `Array` itself) +// are passed to the various `_array__*` functions below to address strict aliasing +// violations that arises when the _entire_ `Array` struct is passed as `Array(void)*`. +// +// The `Array` type itself was not altered as a solution in order to avoid breakage +// with existing consumers (in particular, parsers with external scanners). - /// This is not what you're looking for, see `array_erase`. - static inline void - _array__erase (Array *self, size_t element_size, uint32_t index) - { - assert (index < self->size); - char *contents = (char *)self->contents; - memmove (contents + index * element_size, - contents + (index + 1) * element_size, - (self->size - index - 1) * element_size); - self->size--; - } +/// This is not what you're looking for, see `array_erase`. +static inline void _array__erase(void* self_contents, uint32_t *size, + size_t element_size, uint32_t index) { + assert(index < *size); + char *contents = (char *)self_contents; + memmove(contents + index * element_size, contents + (index + 1) * element_size, + (*size - index - 1) * element_size); + (*size)--; +} - /// This is not what you're looking for, see `array_reserve`. - static inline void - _array__reserve (Array *self, size_t element_size, uint32_t new_capacity) - { - if (new_capacity > self->capacity) - { - if (self->contents) - { - self->contents - = ts_realloc (self->contents, new_capacity * element_size); - } - else - { - self->contents = ts_malloc (new_capacity * element_size); - } - self->capacity = new_capacity; - } +/// This is not what you're looking for, see `array_reserve`. +static inline void *_array__reserve(void *contents, uint32_t *capacity, + size_t element_size, uint32_t new_capacity) { + void *new_contents = contents; + if (new_capacity > *capacity) { + if (contents) { + new_contents = ts_realloc(contents, new_capacity * element_size); + } else { + new_contents = ts_malloc(new_capacity * element_size); + } + *capacity = new_capacity; } + return new_contents; +} - /// This is not what you're looking for, see `array_assign`. - static inline void - _array__assign (Array *self, const Array *other, size_t element_size) - { - _array__reserve (self, element_size, other->size); - self->size = other->size; - memcpy (self->contents, other->contents, self->size * element_size); - } +/// This is not what you're looking for, see `array_assign`. +static inline void *_array__assign(void* self_contents, uint32_t *self_size, uint32_t *self_capacity, + const void *other_contents, uint32_t other_size, size_t element_size) { + void *new_contents = _array__reserve(self_contents, self_capacity, element_size, other_size); + *self_size = other_size; + memcpy(new_contents, other_contents, *self_size * element_size); + return new_contents; +} - /// This is not what you're looking for, see `array_swap`. - static inline void - _array__swap (Array *self, Array *other) - { - Array swap = *other; - *other = *self; - *self = swap; - } +/// This is not what you're looking for, see `array_swap`. +static inline void _array__swap(uint32_t *self_size, uint32_t *self_capacity, + uint32_t *other_size, uint32_t *other_capacity) { + uint32_t tmp_size = *self_size; + uint32_t tmp_capacity = *self_capacity; + *self_size = *other_size; + *self_capacity = *other_capacity; + *other_size = tmp_size; + *other_capacity = tmp_capacity; +} - /// This is not what you're looking for, see `array_push` or `array_grow_by`. - static inline void - _array__grow (Array *self, uint32_t count, size_t element_size) - { - uint32_t new_size = self->size + count; - if (new_size > self->capacity) - { - uint32_t new_capacity = self->capacity * 2; - if (new_capacity < 8) - new_capacity = 8; - if (new_capacity < new_size) - new_capacity = new_size; - _array__reserve (self, element_size, new_capacity); - } +/// This is not what you're looking for, see `array_push` or `array_grow_by`. +static inline void *_array__grow(void *contents, uint32_t size, uint32_t *capacity, + uint32_t count, size_t element_size) { + void *new_contents = contents; + uint32_t new_size = size + count; + if (new_size > *capacity) { + uint32_t new_capacity = *capacity * 2; + if (new_capacity < 8) new_capacity = 8; + if (new_capacity < new_size) new_capacity = new_size; + new_contents = _array__reserve(contents, capacity, element_size, new_capacity); } + return new_contents; +} - /// This is not what you're looking for, see `array_splice`. - static inline void - _array__splice (Array *self, size_t element_size, uint32_t index, - uint32_t old_count, uint32_t new_count, const void *elements) - { - uint32_t new_size = self->size + new_count - old_count; - uint32_t old_end = index + old_count; - uint32_t new_end = index + new_count; - assert (old_end <= self->size); +/// This is not what you're looking for, see `array_splice`. +static inline void *_array__splice(void *self_contents, uint32_t *size, uint32_t *capacity, + size_t element_size, + uint32_t index, uint32_t old_count, + uint32_t new_count, const void *elements) { + uint32_t new_size = *size + new_count - old_count; + uint32_t old_end = index + old_count; + uint32_t new_end = index + new_count; + assert(old_end <= *size); - _array__reserve (self, element_size, new_size); + void *new_contents = _array__reserve(self_contents, capacity, element_size, new_size); - char *contents = (char *)self->contents; - if (self->size > old_end) - { - memmove (contents + new_end * element_size, - contents + old_end * element_size, - (self->size - old_end) * element_size); - } - if (new_count > 0) - { - if (elements) - { - memcpy ((contents + index * element_size), elements, - new_count * element_size); - } - else - { - memset ((contents + index * element_size), 0, - new_count * element_size); - } - } - self->size += new_count - old_count; + char *contents = (char *)new_contents; + if (*size > old_end) { + memmove( + contents + new_end * element_size, + contents + old_end * element_size, + (*size - old_end) * element_size + ); } + if (new_count > 0) { + if (elements) { + memcpy( + (contents + index * element_size), + elements, + new_count * element_size + ); + } else { + memset( + (contents + index * element_size), + 0, + new_count * element_size + ); + } + } + *size += new_count - old_count; + + return new_contents; +} /// A binary search routine, based on Rust's `std::slice::binary_search_by`. -/// This is not what you're looking for, see `array_search_sorted_with` or -/// `array_search_sorted_by`. -#define _array__search_sorted(self, start, compare, suffix, needle, _index, \ - _exists) \ - do \ - { \ - *(_index) = start; \ - *(_exists) = false; \ - uint32_t size = (self)->size - *(_index); \ - if (size == 0) \ - break; \ - int comparison; \ - while (size > 1) \ - { \ - uint32_t half_size = size / 2; \ - uint32_t mid_index = *(_index) + half_size; \ - comparison \ - = compare (&((self)->contents[mid_index] suffix), (needle)); \ - if (comparison <= 0) \ - *(_index) = mid_index; \ - size -= half_size; \ - } \ - comparison = compare (&((self)->contents[*(_index)] suffix), (needle)); \ - if (comparison == 0) \ - *(_exists) = true; \ - else if (comparison < 0) \ - *(_index) += 1; \ - } \ - while (0) +/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. +#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ + do { \ + *(_index) = start; \ + *(_exists) = false; \ + uint32_t size = (self)->size - *(_index); \ + if (size == 0) break; \ + int comparison; \ + while (size > 1) { \ + uint32_t half_size = size / 2; \ + uint32_t mid_index = *(_index) + half_size; \ + comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ + if (comparison <= 0) *(_index) = mid_index; \ + size -= half_size; \ + } \ + comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ + if (comparison == 0) *(_exists) = true; \ + else if (comparison < 0) *(_index) += 1; \ + } while (0) -/// Helper macro for the `_sorted_by` routines below. This takes the left -/// (existing) parameter by reference in order to work with the generic sorting -/// function above. +/// Helper macro for the `_sorted_by` routines below. This takes the left (existing) +/// parameter by reference in order to work with the generic sorting function above. #define _compare_int(a, b) ((int)*(a) - (int)(b)) #ifdef _MSC_VER -#pragma warning(default : 4101) +#pragma warning(pop) #elif defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif @@ -339,4 +327,4 @@ extern "C" } #endif -#endif // TREE_SITTER_ARRAY_H_ +#endif // TREE_SITTER_ARRAY_H_ diff --git a/tree-sitter-yts/src/tree_sitter/parser.h b/tree-sitter-yts/src/tree_sitter/parser.h index aec3b17..858107d 100644 --- a/tree-sitter-yts/src/tree_sitter/parser.h +++ b/tree-sitter-yts/src/tree_sitter/parser.h @@ -1,246 +1,231 @@ -/* - * yt - A fully featured command line YouTube client - * - * Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> - * SPDX-License-Identifier: GPL-3.0-or-later - * - * This file is part of Yt. - * - * You should have received a copy of the License along with this program. - * If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - */ - #ifndef TREE_SITTER_PARSER_H_ #define TREE_SITTER_PARSER_H_ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include <stdbool.h> #include <stdint.h> #include <stdlib.h> -#define ts_builtin_sym_error ((TSSymbol) - 1) +#define ts_builtin_sym_error ((TSSymbol)-1) #define ts_builtin_sym_end 0 #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 #ifndef TREE_SITTER_API_H_ - typedef uint16_t TSStateId; - typedef uint16_t TSSymbol; - typedef uint16_t TSFieldId; - typedef struct TSLanguage TSLanguage; +typedef uint16_t TSStateId; +typedef uint16_t TSSymbol; +typedef uint16_t TSFieldId; +typedef struct TSLanguage TSLanguage; +typedef struct TSLanguageMetadata { + uint8_t major_version; + uint8_t minor_version; + uint8_t patch_version; +} TSLanguageMetadata; #endif - typedef struct - { - TSFieldId field_id; - uint8_t child_index; - bool inherited; - } TSFieldMapEntry; +typedef struct { + TSFieldId field_id; + uint8_t child_index; + bool inherited; +} TSFieldMapEntry; - typedef struct - { - uint16_t index; - uint16_t length; - } TSFieldMapSlice; +// Used to index the field and supertype maps. +typedef struct { + uint16_t index; + uint16_t length; +} TSMapSlice; - typedef struct - { - bool visible; - bool named; - bool supertype; - } TSSymbolMetadata; +typedef struct { + bool visible; + bool named; + bool supertype; +} TSSymbolMetadata; - typedef struct TSLexer TSLexer; +typedef struct TSLexer TSLexer; - struct TSLexer - { - int32_t lookahead; - TSSymbol result_symbol; - void (*advance) (TSLexer *, bool); - void (*mark_end) (TSLexer *); - uint32_t (*get_column) (TSLexer *); - bool (*is_at_included_range_start) (const TSLexer *); - bool (*eof) (const TSLexer *); - void (*log) (const TSLexer *, const char *, ...); - }; +struct TSLexer { + int32_t lookahead; + TSSymbol result_symbol; + void (*advance)(TSLexer *, bool); + void (*mark_end)(TSLexer *); + uint32_t (*get_column)(TSLexer *); + bool (*is_at_included_range_start)(const TSLexer *); + bool (*eof)(const TSLexer *); + void (*log)(const TSLexer *, const char *, ...); +}; - typedef enum - { - TSParseActionTypeShift, - TSParseActionTypeReduce, - TSParseActionTypeAccept, - TSParseActionTypeRecover, - } TSParseActionType; +typedef enum { + TSParseActionTypeShift, + TSParseActionTypeReduce, + TSParseActionTypeAccept, + TSParseActionTypeRecover, +} TSParseActionType; - typedef union - { - struct - { - uint8_t type; - TSStateId state; - bool extra; - bool repetition; - } shift; - struct - { - uint8_t type; - uint8_t child_count; - TSSymbol symbol; - int16_t dynamic_precedence; - uint16_t production_id; - } reduce; +typedef union { + struct { + uint8_t type; + TSStateId state; + bool extra; + bool repetition; + } shift; + struct { uint8_t type; - } TSParseAction; + uint8_t child_count; + TSSymbol symbol; + int16_t dynamic_precedence; + uint16_t production_id; + } reduce; + uint8_t type; +} TSParseAction; - typedef struct - { - uint16_t lex_state; - uint16_t external_lex_state; - } TSLexMode; +typedef struct { + uint16_t lex_state; + uint16_t external_lex_state; +} TSLexMode; - typedef union - { - TSParseAction action; - struct - { - uint8_t count; - bool reusable; - } entry; - } TSParseActionEntry; +typedef struct { + uint16_t lex_state; + uint16_t external_lex_state; + uint16_t reserved_word_set_id; +} TSLexerMode; - typedef struct - { - int32_t start; - int32_t end; - } TSCharacterRange; +typedef union { + TSParseAction action; + struct { + uint8_t count; + bool reusable; + } entry; +} TSParseActionEntry; - struct TSLanguage - { - uint32_t version; - uint32_t symbol_count; - uint32_t alias_count; - uint32_t token_count; - uint32_t external_token_count; - uint32_t state_count; - uint32_t large_state_count; - uint32_t production_id_count; - uint32_t field_count; - uint16_t max_alias_sequence_length; - const uint16_t *parse_table; - const uint16_t *small_parse_table; - const uint32_t *small_parse_table_map; - const TSParseActionEntry *parse_actions; - const char *const *symbol_names; - const char *const *field_names; - const TSFieldMapSlice *field_map_slices; - const TSFieldMapEntry *field_map_entries; - const TSSymbolMetadata *symbol_metadata; - const TSSymbol *public_symbol_map; - const uint16_t *alias_map; - const TSSymbol *alias_sequences; - const TSLexMode *lex_modes; - bool (*lex_fn) (TSLexer *, TSStateId); - bool (*keyword_lex_fn) (TSLexer *, TSStateId); - TSSymbol keyword_capture_token; - struct - { - const bool *states; - const TSSymbol *symbol_map; - void *(*create) (void); - void (*destroy) (void *); - bool (*scan) (void *, TSLexer *, const bool *symbol_whitelist); - unsigned (*serialize) (void *, char *); - void (*deserialize) (void *, const char *, unsigned); - } external_scanner; - const TSStateId *primary_state_ids; - }; +typedef struct { + int32_t start; + int32_t end; +} TSCharacterRange; - static inline bool - set_contains (TSCharacterRange *ranges, uint32_t len, int32_t lookahead) - { - uint32_t index = 0; - uint32_t size = len - index; - while (size > 1) - { - uint32_t half_size = size / 2; - uint32_t mid_index = index + half_size; - TSCharacterRange *range = &ranges[mid_index]; - if (lookahead >= range->start && lookahead <= range->end) - { - return true; - } - else if (lookahead > range->end) - { - index = mid_index; - } - size -= half_size; - } - TSCharacterRange *range = &ranges[index]; - return (lookahead >= range->start && lookahead <= range->end); +struct TSLanguage { + uint32_t abi_version; + uint32_t symbol_count; + uint32_t alias_count; + uint32_t token_count; + uint32_t external_token_count; + uint32_t state_count; + uint32_t large_state_count; + uint32_t production_id_count; + uint32_t field_count; + uint16_t max_alias_sequence_length; + const uint16_t *parse_table; + const uint16_t *small_parse_table; + const uint32_t *small_parse_table_map; + const TSParseActionEntry *parse_actions; + const char * const *symbol_names; + const char * const *field_names; + const TSMapSlice *field_map_slices; + const TSFieldMapEntry *field_map_entries; + const TSSymbolMetadata *symbol_metadata; + const TSSymbol *public_symbol_map; + const uint16_t *alias_map; + const TSSymbol *alias_sequences; + const TSLexerMode *lex_modes; + bool (*lex_fn)(TSLexer *, TSStateId); + bool (*keyword_lex_fn)(TSLexer *, TSStateId); + TSSymbol keyword_capture_token; + struct { + const bool *states; + const TSSymbol *symbol_map; + void *(*create)(void); + void (*destroy)(void *); + bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); + unsigned (*serialize)(void *, char *); + void (*deserialize)(void *, const char *, unsigned); + } external_scanner; + const TSStateId *primary_state_ids; + const char *name; + const TSSymbol *reserved_words; + uint16_t max_reserved_word_set_size; + uint32_t supertype_count; + const TSSymbol *supertype_symbols; + const TSMapSlice *supertype_map_slices; + const TSSymbol *supertype_map_entries; + TSLanguageMetadata metadata; +}; + +static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { + uint32_t index = 0; + uint32_t size = len - index; + while (size > 1) { + uint32_t half_size = size / 2; + uint32_t mid_index = index + half_size; + const TSCharacterRange *range = &ranges[mid_index]; + if (lookahead >= range->start && lookahead <= range->end) { + return true; + } else if (lookahead > range->end) { + index = mid_index; + } + size -= half_size; } + const TSCharacterRange *range = &ranges[index]; + return (lookahead >= range->start && lookahead <= range->end); +} - /* - * Lexer Macros - */ +/* + * Lexer Macros + */ #ifdef _MSC_VER -#define UNUSED __pragma (warning (suppress : 4101)) +#define UNUSED __pragma(warning(suppress : 4101)) #else -#define UNUSED __attribute__ ((unused)) +#define UNUSED __attribute__((unused)) #endif -#define START_LEXER() \ - bool result = false; \ - bool skip = false; \ - UNUSED \ - bool eof = false; \ - int32_t lookahead; \ - goto start; \ - next_state: \ - lexer->advance (lexer, skip); \ - start: \ - skip = false; \ +#define START_LEXER() \ + bool result = false; \ + bool skip = false; \ + UNUSED \ + bool eof = false; \ + int32_t lookahead; \ + goto start; \ + next_state: \ + lexer->advance(lexer, skip); \ + start: \ + skip = false; \ lookahead = lexer->lookahead; -#define ADVANCE(state_value) \ - { \ - state = state_value; \ - goto next_state; \ +#define ADVANCE(state_value) \ + { \ + state = state_value; \ + goto next_state; \ } -#define ADVANCE_MAP(...) \ - { \ - static const uint16_t map[] = { __VA_ARGS__ }; \ - for (uint32_t i = 0; i < sizeof (map) / sizeof (map[0]); i += 2) \ - { \ - if (map[i] == lookahead) \ - { \ - state = map[i + 1]; \ - goto next_state; \ - } \ - } \ +#define ADVANCE_MAP(...) \ + { \ + static const uint16_t map[] = { __VA_ARGS__ }; \ + for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ + if (map[i] == lookahead) { \ + state = map[i + 1]; \ + goto next_state; \ + } \ + } \ } -#define SKIP(state_value) \ - { \ - skip = true; \ - state = state_value; \ - goto next_state; \ +#define SKIP(state_value) \ + { \ + skip = true; \ + state = state_value; \ + goto next_state; \ } -#define ACCEPT_TOKEN(symbol_value) \ - result = true; \ - lexer->result_symbol = symbol_value; \ - lexer->mark_end (lexer); +#define ACCEPT_TOKEN(symbol_value) \ + result = true; \ + lexer->result_symbol = symbol_value; \ + lexer->mark_end(lexer); #define END_STATE() return result; - /* - * Parse Table Macros - */ +/* + * Parse Table Macros + */ #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) @@ -248,57 +233,54 @@ extern "C" #define ACTIONS(id) id -#define SHIFT(state_value) \ - { \ - { \ - .shift = {.type = TSParseActionTypeShift, .state = (state_value) } \ - } \ - } +#define SHIFT(state_value) \ + {{ \ + .shift = { \ + .type = TSParseActionTypeShift, \ + .state = (state_value) \ + } \ + }} -#define SHIFT_REPEAT(state_value) \ - { \ - { \ - .shift \ - = {.type = TSParseActionTypeShift, \ - .state = (state_value), \ - .repetition = true } \ - } \ - } +#define SHIFT_REPEAT(state_value) \ + {{ \ + .shift = { \ + .type = TSParseActionTypeShift, \ + .state = (state_value), \ + .repetition = true \ + } \ + }} -#define SHIFT_EXTRA() \ - { \ - { \ - .shift = {.type = TSParseActionTypeShift, .extra = true } \ - } \ - } +#define SHIFT_EXTRA() \ + {{ \ + .shift = { \ + .type = TSParseActionTypeShift, \ + .extra = true \ + } \ + }} -#define REDUCE(symbol_name, children, precedence, prod_id) \ - { \ - { \ - .reduce = { .type = TSParseActionTypeReduce, \ - .symbol = symbol_name, \ - .child_count = children, \ - .dynamic_precedence = precedence, \ - .production_id = prod_id }, \ - } \ - } +#define REDUCE(symbol_name, children, precedence, prod_id) \ + {{ \ + .reduce = { \ + .type = TSParseActionTypeReduce, \ + .symbol = symbol_name, \ + .child_count = children, \ + .dynamic_precedence = precedence, \ + .production_id = prod_id \ + }, \ + }} -#define RECOVER() \ - { \ - { \ - .type = TSParseActionTypeRecover \ - } \ - } +#define RECOVER() \ + {{ \ + .type = TSParseActionTypeRecover \ + }} -#define ACCEPT_INPUT() \ - { \ - { \ - .type = TSParseActionTypeAccept \ - } \ - } +#define ACCEPT_INPUT() \ + {{ \ + .type = TSParseActionTypeAccept \ + }} #ifdef __cplusplus } #endif -#endif // TREE_SITTER_PARSER_H_ +#endif // TREE_SITTER_PARSER_H_ diff --git a/tree-sitter-yts/tree-sitter.json b/tree-sitter-yts/tree-sitter.json index f1a0586..33c2b6e 100644 --- a/tree-sitter-yts/tree-sitter.json +++ b/tree-sitter-yts/tree-sitter.json @@ -1,29 +1,40 @@ { + "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/config.schema.json", "grammars": [ { - "name": "yts", - "camelcase": "Yts", + "name": "YTS", + "camelcase": "YTS", + "title": "YTS", "scope": "source.yts", - "path": ".", - "file-types": ["yts"], - "highlights": ["queries/highlights.scm"], - "injection-regex": "^(yts)$" + "file-types": [ + "yts" + ], + "injection-regex": "^yts$", + "class-name": "TreeSitterYts" } ], "metadata": { - "version": "0.0.1", - "license": "MIT", - "description": "yts grammar for tree-sitter", + "version": "0.1.0", + "license": "GPL-3-or-later", + "description": "Parser for yt's selection language", + "authors": [ + { + "name": "Benedikt Peetz", + "email": "benedikt.peetz@b-peetz.de" + } + ], "links": { - "repository": "https://git.vhack.eu/soispha/clients/yt/tree-sitter-yts" + "repository": "https://git.foss-syndicate.org/bpeetz/clients/yt" } }, "bindings": { - "c": true, - "go": true, - "node": true, - "python": true, + "c": false, + "go": false, + "java": false, + "node": false, + "python": false, "rust": true, - "swift": true + "swift": false, + "zig": false } } diff --git a/tree-sitter-yts/tree-sitter.json.license b/tree-sitter-yts/tree-sitter.json.license deleted file mode 100644 index d4d410f..0000000 --- a/tree-sitter-yts/tree-sitter.json.license +++ /dev/null @@ -1,9 +0,0 @@ -yt - A fully featured command line YouTube client - -Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of Yt. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. @@ -14,7 +14,4 @@ nix flake update [ "$1" = "upgrade" ] && cargo upgrade --incompatible allow --pinned allow --recursive true cargo update --recursive - -./crates/yt_dlp/update.sh "$@" -./crates/libmpv2/update.sh "$@" # vim: ft=sh |
