ratatui-macros-0.7.0/.cargo_vcs_info.json0000644000000001540000000000100137730ustar { "git": { "sha1": "0a2a7c0363a4806b0cf05c1915bf7cdd438f756c" }, "path_in_vcs": "ratatui-macros" }ratatui-macros-0.7.0/.rustfmt.toml000064400000000000000000000000701046102023000152370ustar 00000000000000format_macro_bodies = true format_macro_matchers = true ratatui-macros-0.7.0/CHANGELOG.md000064400000000000000000000133451046102023000144020ustar 00000000000000# Changelog See the [top-level changelog](../CHANGELOG.md) for the latest changes. This file is obsolete as of 0.30.0 release. [\*](https://github.com/ratatui/ratatui/pull/1652) ## [0.6.0](https://github.com/ratatui/ratatui-macros/compare/v0.5.0...v0.6.0) - 2024-10-21 ### Other - *(deps)* bump the cargo-dependencies group with 2 updates ([#73](https://github.com/ratatui/ratatui-macros/pull/73)) - *(deps)* bump ratatui from 0.28.0 to 0.28.1 in the cargo-dependencies group ([#70](https://github.com/ratatui/ratatui-macros/pull/70)) ## [0.5.0] - 2024-08-12 ### 🐛 Bug Fixes - Bump version to 0.5.0 ## [0.4.4](https://github.com/ratatui-org/ratatui-macros/compare/v0.4.3...v0.4.4) - 2024-08-09 ### Other - *(deps)* bump ratatui to 0.28.0 ([#66](https://github.com/ratatui-org/ratatui-macros/pull/66)) - *(deps)* bump trybuild from 1.0.98 to 1.0.99 in the cargo-dependencies group ([#65](https://github.com/ratatui-org/ratatui-macros/pull/65)) - *(deps)* bump trybuild from 1.0.97 to 1.0.98 in the cargo-dependencies group ([#62](https://github.com/ratatui-org/ratatui-macros/pull/62)) ## [0.4.3](https://github.com/ratatui-org/ratatui-macros/compare/v0.4.2...v0.4.3) - 2024-07-22 ### Added - allow span macro to accept a bare expression ([#61](https://github.com/ratatui-org/ratatui-macros/pull/61)) ### Other - *(deps)* bump trybuild from 1.0.96 to 1.0.97 in the cargo-dependencies group ([#59](https://github.com/ratatui-org/ratatui-macros/pull/59)) ## [0.4.2](https://github.com/ratatui-org/ratatui-macros/compare/v0.4.1...v0.4.2) - 2024-06-29 ### Added - Use `::ratatui` instead of `ratatui` ([#54](https://github.com/ratatui-org/ratatui-macros/pull/54)) - Add row! macro ([#52](https://github.com/ratatui-org/ratatui-macros/pull/52)) ### Other - Update README with row! documentation ([#56](https://github.com/ratatui-org/ratatui-macros/pull/56)) - Make doc examples shorter by removing duplicate imports ([#55](https://github.com/ratatui-org/ratatui-macros/pull/55)) ## [0.4.1](https://github.com/ratatui-org/ratatui-macros/compare/v0.4.0...v0.4.1) - 2024-06-24 ### Other - *(deps)* bump ratatui from 0.26.3 to 0.27.0 in the cargo-dependencies group ([#51](https://github.com/ratatui-org/ratatui-macros/pull/51)) - Update dependabot.yml to group dependencies ([#50](https://github.com/ratatui-org/ratatui-macros/pull/50)) - *(deps)* bump ratatui from 0.26.2 to 0.26.3 ([#48](https://github.com/ratatui-org/ratatui-macros/pull/48)) - *(deps)* bump trybuild from 1.0.95 to 1.0.96 ([#47](https://github.com/ratatui-org/ratatui-macros/pull/47)) ## [0.4.0](https://github.com/ratatui-org/ratatui-macros/compare/v0.3.1...v0.4.0) - 2024-05-15 ### Added - *(layout)* [**breaking**] Use `*=` instead of `=*` ([#45](https://github.com/ratatui-org/ratatui-macros/pull/45)) ## [0.3.1](https://github.com/ratatui-org/ratatui-macros/compare/v0.3.0...v0.3.1) - 2024-05-13 ### Added - Better error messages for `span!` macro ([#43](https://github.com/ratatui-org/ratatui-macros/pull/43)) ### Fixed - downgrade ratatui to 0.26.2 ([#41](https://github.com/ratatui-org/ratatui-macros/pull/41)) ### Other - Update authors to ratatui developers ([#44](https://github.com/ratatui-org/ratatui-macros/pull/44)) ## [0.3.0](https://github.com/ratatui-org/ratatui-macros/compare/v0.2.4...v0.3.0) - 2024-05-09 ### Added - Use release-plz ([#38](https://github.com/ratatui-org/ratatui-macros/pull/38)) - Add text! macro ([#36](https://github.com/ratatui-org/ratatui-macros/pull/36)) - Add fill constraint ([#34](https://github.com/ratatui-org/ratatui-macros/pull/34)) - [**breaking**] Remove color `palette!` macro ([#32](https://github.com/ratatui-org/ratatui-macros/pull/32)) - Replace raw! and styled! with span! macro ([#30](https://github.com/ratatui-org/ratatui-macros/pull/30)) - Add `line!` attribute macro ([#29](https://github.com/ratatui-org/ratatui-macros/pull/29)) - *(text)* add raw! and styled! macros ([#4](https://github.com/ratatui-org/ratatui-macros/pull/4)) ### Fixed - Update repo url in Cargo.toml ([#39](https://github.com/ratatui-org/ratatui-macros/pull/39)) ### Other - Use `.areas(area)` instead of `.split(area).to_vec().try_into().unwrap()` ([#37](https://github.com/ratatui-org/ratatui-macros/pull/37)) - Update README.md with short description of span and line macros ([#33](https://github.com/ratatui-org/ratatui-macros/pull/33)) - format using cargo +nightly fmt ([#31](https://github.com/ratatui-org/ratatui-macros/pull/31)) - *(deps)* bump ratatui from 0.27.0-alpha.3 to 0.27.0-alpha.5 ([#27](https://github.com/ratatui-org/ratatui-macros/pull/27)) - *(deps)* bump trybuild from 1.0.91 to 1.0.93 ([#28](https://github.com/ratatui-org/ratatui-macros/pull/28)) - *(deps)* bump ratatui from 0.27.0-alpha.2 to 0.27.0-alpha.3 ([#24](https://github.com/ratatui-org/ratatui-macros/pull/24)) - *(deps)* bump trybuild from 1.0.90 to 1.0.91 ([#23](https://github.com/ratatui-org/ratatui-macros/pull/23)) - *(deps)* bump trybuild from 1.0.88 to 1.0.90 ([#20](https://github.com/ratatui-org/ratatui-macros/pull/20)) - *(deps)* bump ratatui from 0.27.0-alpha.0 to 0.27.0-alpha.2 ([#22](https://github.com/ratatui-org/ratatui-macros/pull/22)) - *(deps)* bump mio from 0.8.10 to 0.8.11 ([#18](https://github.com/ratatui-org/ratatui-macros/pull/18)) - *(deps)* bump ratatui from 0.26.0-alpha.1 to 0.27.0-alpha.0 ([#19](https://github.com/ratatui-org/ratatui-macros/pull/19)) - add cargo husky pre-commit hook ([#8](https://github.com/ratatui-org/ratatui-macros/pull/8)) - Create dependabot.yml ([#7](https://github.com/ratatui-org/ratatui-macros/pull/7)) - use rust cache to cache deps ([#6](https://github.com/ratatui-org/ratatui-macros/pull/6)) - readme tweaks ([#5](https://github.com/ratatui-org/ratatui-macros/pull/5)) - Update README.md - Update README.md - Update README.md - Update README.md - Add link to ratatui ratatui-macros-0.7.0/Cargo.lock0000644000000414320000000000100117520ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "allocator-api2" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "bitflags" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "castaway" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ "rustversion", ] [[package]] name = "cfg-if" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "compact_str" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" dependencies = [ "castaway", "cfg-if", "itoa", "rustversion", "ryu", "static_assertions", ] [[package]] name = "darling" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", ] [[package]] name = "darling_core" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", "syn", ] [[package]] name = "darling_macro" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", "syn", ] [[package]] name = "deranged" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", ] [[package]] name = "dissimilar" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "glob" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", "foldhash", ] [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown 0.15.5", ] [[package]] name = "indoc" version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" dependencies = [ "rustversion", ] [[package]] name = "instability" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6778b0196eefee7df739db78758e5cf9b37412268bfa5650bfeed028aed20d9c" dependencies = [ "darling", "indoc", "proc-macro2", "quote", "syn", ] [[package]] name = "itertools" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itertools" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "kasuari" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b" dependencies = [ "hashbrown 0.16.1", "thiserror", ] [[package]] name = "line-clipping" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4de44e98ddbf09375cbf4d17714d18f39195f4f4894e8524501726fd9a8a4a" dependencies = [ "bitflags", ] [[package]] name = "lru" version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" dependencies = [ "hashbrown 0.16.1", ] [[package]] name = "memchr" version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "ratatui-core" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" dependencies = [ "bitflags", "compact_str", "hashbrown 0.16.1", "indoc", "itertools 0.14.0", "kasuari", "lru", "strum", "thiserror", "unicode-segmentation", "unicode-truncate", "unicode-width", ] [[package]] name = "ratatui-macros" version = "0.7.0" dependencies = [ "ratatui-core", "ratatui-widgets", "trybuild", ] [[package]] name = "ratatui-widgets" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" dependencies = [ "bitflags", "hashbrown 0.16.1", "indoc", "instability", "itertools 0.14.0", "line-clipping", "ratatui-core", "strum", "time", "unicode-segmentation", "unicode-width", ] [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.146" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" dependencies = [ "itoa", "memchr", "ryu", "serde", "serde_core", ] [[package]] name = "serde_spanned" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" dependencies = [ "serde", ] [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "syn" version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "target-triple" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "time" version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "num-conv", "powerfmt", "time-core", ] [[package]] name = "time-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "toml" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "toml_parser", "toml_writer", "winnow", ] [[package]] name = "toml_datetime" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" dependencies = [ "serde", ] [[package]] name = "toml_parser" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" dependencies = [ "winnow", ] [[package]] name = "toml_writer" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" [[package]] name = "trybuild" version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", "target-triple", "termcolor", "toml", ] [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-segmentation" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-truncate" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fbf03860ff438702f3910ca5f28f8dac63c1c11e7efb5012b8b175493606330" dependencies = [ "itertools 0.13.0", "unicode-segmentation", "unicode-width", ] [[package]] name = "unicode-width" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" ratatui-macros-0.7.0/Cargo.toml0000644000000023200000000000100117660ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2024" name = "ratatui-macros" version = "0.7.0" authors = ["The Ratatui Developers"] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Macros for Ratatui" documentation = "https://docs.rs/ratatui-macros" readme = "README.md" keywords = [ "ratatui", "macros", "tui", "ui", ] categories = ["command-line-interface"] license = "MIT" repository = "https://github.com/ratatui/ratatui" resolver = "2" [lib] name = "ratatui_macros" path = "src/lib.rs" [[test]] name = "macros" path = "tests/macros.rs" [dependencies.ratatui-core] version = "0.1.0" [dependencies.ratatui-widgets] version = "0.3.0" [dev-dependencies.trybuild] version = "1" features = ["diff"] ratatui-macros-0.7.0/Cargo.toml.orig000064400000000000000000000007661046102023000154630ustar 00000000000000[package] name = "ratatui-macros" version = "0.7.0" description = "Macros for Ratatui" edition.workspace = true authors = ["The Ratatui Developers"] license = "MIT" repository = "https://github.com/ratatui/ratatui" documentation = "https://docs.rs/ratatui-macros" keywords = ["ratatui", "macros", "tui", "ui"] categories = ["command-line-interface"] [dependencies] ratatui-core.workspace = true ratatui-widgets.workspace = true [dev-dependencies] trybuild = { workspace = true, features = ["diff"] } ratatui-macros-0.7.0/LICENSE000064400000000000000000000021231046102023000135660ustar 00000000000000Copyright (c) 2024 Dheepak Krishnamurthy Copyright (c) 2025 The Ratatui Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ratatui-macros-0.7.0/README.md000064400000000000000000000124271046102023000140500ustar 00000000000000# Ratatui Macros [![Crates.io badge]][ratatui_macros crate] [![License badge]](./LICENSE) [![Docs.rs badge]][API Docs] [![CI Badge]][CI Status] [![Crate Downloads badge]][ratatui_macros crate] `ratatui-macros` is a Rust crate that provides easy-to-use macros for simplifying boilerplate associated with creating UI using [Ratatui]. This is an experimental playground for us to explore macros that would be useful to have in Ratatui proper. ## Features - [Text macros](#text-macros) for easily defining styled [`Text`]s, [`Line`]s, and [`Span`]s. - [Layout macros](#layout-macros) for defining [`Layout`]s with [`Constraint`]s and directions. - [Table macros](#table-macros) for creating [`Row`]s and [`Cell`]s. ## Getting Started Add `ratatui-macros` as a dependency in your `Cargo.toml`: ```shell cargo add ratatui-macros ``` Then, import the macros in your Rust file: ```rust use ratatui_macros::{constraint, constraints, horizontal, line, row, span, text, vertical}; ``` ## Text Macros The [`span!`] macro creates raw or styled [`Span`]s. ```rust let name = "world!"; let raw_greeting = span!("hello {name}"); let styled_greeting = span!(Style::new().green(); "hello {name}"); let colored_greeting = span!(Color::Green; "hello {name}"); let modified_greeting = span!(Modifier::BOLD; "hello {name}"); ``` The [`line!`] macro creates a [`Line`] that contains a sequence of [`Span`]s. It is similar to the [`vec!`] macro. Each element is converted into a [`Span`] using [`Into::into`]. ```rust let name = "world!"; let line = line!["hello", format!("{name}")]; let line = line!["hello ", span!(Color::Green; "{name}")]; let line = line!["Name: ".bold(), "Remy".italic()]; let line = line!["bye"; 2]; ``` The [`text!`] macro creates a [`Text`] that contains a sequence of [`Line`]. It is similar to the [`vec!`] macro. Each element is converted to a [`Line`] using [`Into::into`]. ```rust let name = "world!"; let text = text!["hello", format!("{name}")]; let text = text!["bye"; 2]; let name = "Bye!!!"; let text = text![line!["hello", "world".bold()], span!(Modifier::BOLD; "{name}")]; ``` ## Layout Macros If you are new to Ratatui, check out the [Layout concepts] article on the Ratatui website before proceeding. The [`constraints!`] macro defines an array of [`Constraint`]s: ```rust let layout = Layout::horizontal(constraints![==50, ==30%, >=3, <=1, ==1/2, *=1]); ``` The [`constraint!`] macro defines individual [`Constraint`]s: ```rust let layout = Layout::horizontal([constraint!(==50)]); ``` The [`vertical!`] and [`horizontal!`] macros are a shortcut to defining a [`Layout`]: ```rust let [top, main, bottom] = vertical![==1, *=1, >=3].areas(area); let [left, main, right] = horizontal![>=20, *=1, >=20].areas(main); ``` ## Table Macros The [`row!`] macro creates a [`Row`] for a [`Table`] that contains a sequence of [`Cell`]s. It is similar to the [`vec!`] macro. ```rust let rows = [ row!["hello", "world"], row!["goodbye", "world"], row![ text!["line 1", line!["Line", "2".bold()]], span!(Modifier::BOLD; "Cell 2"), ], ]; let table = Table::new(rows, constraints![==20, *=1]); ``` ## Contributing Contributions to `ratatui-macros` are welcome! Whether it's submitting a bug report, a feature request, or a pull request, all forms of contributions are valued and appreciated. ## Crate Organization `ratatui-macros` is part of the Ratatui workspace that was modularized in version 0.30.0. This crate provides declarative macros to reduce boilerplate when working with Ratatui. **When to use `ratatui-macros`:** - You want to reduce boilerplate when creating styled text, layouts, or tables - You prefer macro-based syntax for creating UI elements - You need compile-time generation of repetitive UI code **When to use the main [`ratatui`] crate:** - Building applications (recommended - includes macros when the `macros` feature is enabled) - You want the convenience of having everything available For detailed information about the workspace organization, see [ARCHITECTURE.md]. [`ratatui`]: https://crates.io/crates/ratatui [ARCHITECTURE.md]: https://github.com/ratatui/ratatui/blob/main/ARCHITECTURE.md [Crates.io badge]: https://img.shields.io/crates/v/ratatui-macros?logo=rust&style=flat-square [License badge]: https://img.shields.io/crates/l/ratatui-macros [CI Badge]: https://img.shields.io/github/actions/workflow/status/ratatui/ratatui/ci.yml?logo=github&style=flat-square [Docs.rs badge]: https://img.shields.io/docsrs/ratatui-macros?logo=rust&style=flat-square [Crate Downloads badge]: https://img.shields.io/crates/d/ratatui-macros?logo=rust&style=flat-square [ratatui_macros crate]: https://crates.io/crates/ratatui-macros [API Docs]: https://docs.rs/ratatui-macros [CI Status]: https://github.com/ratatui/ratatui/actions [Ratatui]: https://github.com/ratatui/ratatui [Layout concepts]: https://ratatui.rs/concepts/layout [`Constraint`]: ratatui_core::layout::Constraint [`Layout`]: ratatui_core::layout::Layout [`Span`]: ratatui_core::text::Span [`Line`]: ratatui_core::text::Line [`Text`]: ratatui_core::text::Text [`Row`]: ratatui_widgets::table::Row [`Cell`]: ratatui_widgets::table::Cell [`Table`]: ratatui_widgets::table::Table ratatui-macros-0.7.0/src/layout.rs000064400000000000000000000220571046102023000152430ustar 00000000000000/// Creates a single constraint. /// /// If creating an array of constraints, you probably want to use /// [`constraints!`] instead. /// /// # Examples /// /// ``` /// # use ratatui_core::layout::Constraint; /// use ratatui_macros::constraint; /// assert_eq!(constraint!(>= 3 + 4), Constraint::Min(7)); /// assert_eq!(constraint!(<= 3 + 4), Constraint::Max(7)); /// assert_eq!(constraint!(== 1 / 3), Constraint::Ratio(1, 3)); /// assert_eq!(constraint!(== 3), Constraint::Length(3)); /// assert_eq!(constraint!(== 10 %), Constraint::Percentage(10)); /// assert_eq!(constraint!(*= 1), Constraint::Fill(1)); /// ``` /// /// [`constraints!`]: crate::constraints #[macro_export] macro_rules! constraint { (== $token:tt %) => { $crate::ratatui_core::layout::Constraint::Percentage($token) }; (>= $expr:expr) => { $crate::ratatui_core::layout::Constraint::Min($expr) }; (<= $expr:expr) => { $crate::ratatui_core::layout::Constraint::Max($expr) }; (== $num:tt / $denom:tt) => { $crate::ratatui_core::layout::Constraint::Ratio($num as u32, $denom as u32) }; (== $expr:expr) => { $crate::ratatui_core::layout::Constraint::Length($expr) }; (*= $expr:expr) => { $crate::ratatui_core::layout::Constraint::Fill($expr) }; } /// Creates an array of constraints. /// /// See [`constraint!`] for more information. /// /// If you want to solve the constraints, see /// [`vertical!`] and [`horizontal!`] macros. /// /// # Examples /// /// ```rust /// use ratatui_macros::constraints; /// assert_eq!(constraints![==5, ==30%, >=3, <=1, ==1/2].len(), 5); /// assert_eq!(constraints![==5; 5].len(), 5); /// ``` /// /// ```rust /// # use ratatui_core::layout::Constraint; /// # use ratatui_macros::constraints; /// assert_eq!( /// constraints![==50, ==30%, >=3, <=1, ==1/2, *=1], /// [ /// Constraint::Length(50), /// Constraint::Percentage(30), /// Constraint::Min(3), /// Constraint::Max(1), /// Constraint::Ratio(1, 2), /// Constraint::Fill(1), /// ] /// ) /// ``` /// /// [`constraint!`]: crate::constraint /// [`vertical!`]: crate::vertical /// [`horizontal!`]: crate::horizontal #[macro_export] macro_rules! constraints { // Note: this implementation forgoes speed for the sake of simplicity. Adding variations of the // comma and semicolon rules for each constraint type would be faster, but would result in a lot // of duplicated code. // Cannot start the constraints macro with a , ([ , $($rest:tt)* ] -> () []) => { compile_error!("No rules expected the token `,` while trying to match the end of the macro") }; // Comma finishes a constraint element, so parse it and continue. // When a comma is encountered, it marks the end of a constraint element, so this rule is responsible // for parsing the constraint expression up to the comma and continuing the parsing process. // It accumulated the $partial contains a Constraint and is parsed using a separate $crate::constraint! macro. // The constraint is then appended to the list of parsed constraints. // // [ , $($rest:tt)* ] -> In the rule matcher, this pattern matches a comma followed // by the rest of the tokens. The comma signals the end of // the current constraint element. // ($($partial:tt)*) -> In the rule matcher, this contains the partial tokens // accumulated so far for the current constraint element. // [$($parsed:tt)* ] -> This contains the constraints that have been successfully // parsed so far. // $crate::constraint!($($partial)*) -> This macro call parses and expands the accumulated // partial tokens into a single Constraint expression. // [$($parsed)* $crate::constraint!(...)] -> Appends the newly parsed constraint to the list of // already parsed constraints. ([ , $($rest:tt)* ] -> ($($partial:tt)*) [ $($parsed:tt)* ]) => { $crate::constraints!([$($rest)*] -> () [$($parsed)* $crate::constraint!($($partial)*) ,]) }; // Semicolon indicates that there's repetition. The trailing comma is required because the 'entrypoint' // rule adds a trailing comma. // This rule is triggered when a semicolon is encountered, indicating that there is repetition of // constraints. It handles the repetition logic by parsing the count and generating an array of // constraints using the $crate::constraint! macro. // // [ ; $count:expr , ] -> In the rule matcher, this pattern matches a semicolon // followed by an expression representing the count, and a // trailing comma. // ($($partial:tt)*) -> In the rule matcher, this contains the partial tokens // accumulated so far for the current constraint element. // This represents everything before the ; // [] -> There will be no existed parsed constraints when using ; // $crate::constraint!($($partial)*) -> This macro call parses and expands the accumulated // partial tokens into a single Constraint expression. // [$crate::constraint!(...) ; $count] -> Generates an array of constraints by repeating the // parsed constraint count number of times. ([ ; $count:expr , ] -> ($($partial:tt)*) []) => { [$crate::constraint!($($partial)*); $count] }; // Pull the first token (which can't be a comma or semicolon) onto the accumulator. // if first token is a comma or semicolon, previous rules will match before this rule // // [ $head:tt $($rest:tt)* ] -> In the rule matcher, this pulls a single `head` token // out of the previous rest, and puts // the remaining into `rest` // [ $($rest)* ] -> This is what is fed back into the `constraints!` macro // as the first segment for the match rule // // ($($partial:tt)*) -> In the rule matcher, this contains previous partial // tokens that will make up a `Constraint` expression // ($($partial)* $head) -> This combines head with the previous partial tokens // i.e. this is the accumulated tokens // // [ $($parsed:tt)* ] -> In the rule matcher, this contains all parsed exprs // [$($parsed)* ] -> These are passed on to the next match untouched. ([ $head:tt $($rest:tt)* ] -> ($($partial:tt)*) [ $($parsed:tt)* ]) => { $crate::constraints!([$($rest)*] -> ($($partial)* $head) [$($parsed)* ]) }; // This rule is triggered when there are no more input tokens to process. It signals the end of the // macro invocation and outputs the parsed constraints as a final array. ([$(,)?] -> () [ $( $parsed:tt )* ]) => { [$($parsed)*] }; // Entrypoint where there's no comma at the end. // We add a comma to make sure there's always a trailing comma. // Right-hand side will accumulate the actual `Constraint` literals. ($( $constraint:tt )+) => { $crate::constraints!([ $($constraint)+ , ] -> () []) }; } /// Creates a vertical layout with specified constraints. /// /// It accepts a series of constraints and applies them to create a vertical layout. The constraints /// can include fixed sizes, minimum and maximum sizes, percentages, and ratios. /// /// See [`constraint!`] or [`constraints!`] for more information. /// /// # Examples /// /// ``` /// // Vertical layout with a fixed size and a percentage constraint /// use ratatui_macros::vertical; /// vertical![== 50, == 30%]; /// ``` #[macro_export] macro_rules! vertical { ($( $constraint:tt )+) => { $crate::ratatui_core::layout::Layout::vertical($crate::constraints!( $($constraint)+ )) }; } /// Creates a horizontal layout with specified constraints. /// /// It takes a series of constraints and applies them to create a horizontal layout. The constraints /// can include fixed sizes, minimum and maximum sizes, percentages, and ratios. /// /// See [`constraint!`] or [`constraints!`] for more information. /// /// # Examples /// /// ``` /// // Horizontal layout with a ratio constraint and a minimum size constraint /// use ratatui_macros::horizontal; /// horizontal![== 1/3, >= 100]; /// ``` #[macro_export] macro_rules! horizontal { ($( $constraint:tt )+) => { $crate::ratatui_core::layout::Layout::horizontal($crate::constraints!( $($constraint)+ )) }; } ratatui-macros-0.7.0/src/lib.rs000064400000000000000000000146251046102023000144760ustar 00000000000000#![no_std] //! `ratatui-macros` is a Rust crate that provides easy-to-use macros for simplifying boilerplate //! associated with creating UI using [Ratatui]. //! //! This is an experimental playground for us to explore macros that would be useful to have in //! Ratatui proper. //! //! # Features //! //! - [Text macros](#text-macros) for easily defining styled [`Text`]s, [`Line`]s, and [`Span`]s. //! - [Layout macros](#layout-macros) for defining [`Layout`]s with [`Constraint`]s and directions. //! - [Table macros](#table-macros) for creating [`Row`]s and [`Cell`]s. //! //! # Getting Started //! //! Add `ratatui-macros` as a dependency in your `Cargo.toml`: //! //! ```shell //! cargo add ratatui-macros //! ``` //! //! Then, import the macros in your Rust file: //! //! ```rust //! use ratatui_macros::{constraint, constraints, horizontal, line, row, span, text, vertical}; //! ``` //! //! # Text Macros //! //! The [`span!`] macro creates raw or styled [`Span`]s. //! //! ```rust //! # use ratatui_core::style::{Color, Modifier, Style, Stylize}; //! # use ratatui_macros::span; //! let name = "world!"; //! let raw_greeting = span!("hello {name}"); //! let styled_greeting = span!(Style::new().green(); "hello {name}"); //! let colored_greeting = span!(Color::Green; "hello {name}"); //! let modified_greeting = span!(Modifier::BOLD; "hello {name}"); //! ``` //! //! The [`line!`] macro creates a [`Line`] that contains a sequence of [`Span`]s. It is similar to //! the [`vec!`] macro. Each element is converted into a [`Span`] using [`Into::into`]. //! //! ```rust //! # use ratatui_core::style::{Color, Stylize}; //! # use ratatui_macros::{line, span}; //! let name = "world!"; //! let line = line!["hello", format!("{name}")]; //! let line = line!["hello ", span!(Color::Green; "{name}")]; //! let line = line!["Name: ".bold(), "Remy".italic()]; //! let line = line!["bye"; 2]; //! ``` //! //! The [`text!`] macro creates a [`Text`] that contains a sequence of [`Line`]. It is similar to //! the [`vec!`] macro. Each element is converted to a [`Line`] using [`Into::into`]. //! //! ```rust //! # use ratatui_core::style::{Modifier, Stylize}; //! # use ratatui_macros::{span, line, text}; //! let name = "world!"; //! let text = text!["hello", format!("{name}")]; //! let text = text!["bye"; 2]; //! let name = "Bye!!!"; //! let text = text![line!["hello", "world".bold()], span!(Modifier::BOLD; "{name}")]; //! ``` //! //! # Layout Macros //! //! If you are new to Ratatui, check out the [Layout concepts] article on the Ratatui website before //! proceeding. //! //! The [`constraints!`] macro defines an array of [`Constraint`]s: //! //! ```rust //! # use ratatui_core::layout::Layout; //! # use ratatui_macros::constraints; //! let layout = Layout::horizontal(constraints![==50, ==30%, >=3, <=1, ==1/2, *=1]); //! ``` //! //! The [`constraint!`] macro defines individual [`Constraint`]s: //! //! ```rust //! # use ratatui_core::layout::Layout; //! # use ratatui_macros::constraint; //! let layout = Layout::horizontal([constraint!(==50)]); //! ``` //! //! The [`vertical!`] and [`horizontal!`] macros are a shortcut to defining a [`Layout`]: //! //! ```rust //! # use ratatui_core::layout::Rect; //! # use ratatui_macros::{vertical, horizontal}; //! # let area = Rect { x: 0, y: 0, width: 10, height: 10 }; //! let [top, main, bottom] = vertical![==1, *=1, >=3].areas(area); //! let [left, main, right] = horizontal![>=20, *=1, >=20].areas(main); //! ``` //! //! # Table Macros //! //! The [`row!`] macro creates a [`Row`] for a [`Table`] that contains a sequence of [`Cell`]s. It //! is similar to the [`vec!`] macro. //! //! ```rust //! # use ratatui_core::style::{Modifier, Stylize}; //! # use ratatui_macros::{constraints, line, row, span, text}; //! # use ratatui_widgets::table::Table; //! let rows = [ //! row!["hello", "world"], //! row!["goodbye", "world"], //! row![ //! text!["line 1", line!["Line", "2".bold()]], //! span!(Modifier::BOLD; "Cell 2"), //! ], //! ]; //! let table = Table::new(rows, constraints![==20, *=1]); //! ``` //! //! # Contributing //! //! Contributions to `ratatui-macros` are welcome! Whether it's submitting a bug report, a feature //! request, or a pull request, all forms of contributions are valued and appreciated. //! //! # Crate Organization //! //! `ratatui-macros` is part of the Ratatui workspace that was modularized in version 0.30.0. //! This crate provides declarative macros to reduce boilerplate when working with //! Ratatui. //! //! **When to use `ratatui-macros`:** //! //! - You want to reduce boilerplate when creating styled text, layouts, or tables //! - You prefer macro-based syntax for creating UI elements //! - You need compile-time generation of repetitive UI code //! //! **When to use the main [`ratatui`] crate:** //! //! - Building applications (recommended - includes macros when the `macros` feature is enabled) //! - You want the convenience of having everything available //! //! For detailed information about the workspace organization, see [ARCHITECTURE.md]. //! //! [`ratatui`]: https://crates.io/crates/ratatui //! [ARCHITECTURE.md]: https://github.com/ratatui/ratatui/blob/main/ARCHITECTURE.md //! //! [Crates.io badge]: https://img.shields.io/crates/v/ratatui-macros?logo=rust&style=flat-square //! [License badge]: https://img.shields.io/crates/l/ratatui-macros //! [CI Badge]: //! https://img.shields.io/github/actions/workflow/status/ratatui/ratatui/ci.yml?logo=github&style=flat-square //! [Docs.rs badge]: https://img.shields.io/docsrs/ratatui-macros?logo=rust&style=flat-square //! [Crate Downloads badge]: //! https://img.shields.io/crates/d/ratatui-macros?logo=rust&style=flat-square //! [ratatui_macros crate]: https://crates.io/crates/ratatui-macros //! [API Docs]: https://docs.rs/ratatui-macros //! [CI Status]: https://github.com/ratatui/ratatui/actions //! [Ratatui]: https://github.com/ratatui/ratatui //! [Layout concepts]: https://ratatui.rs/concepts/layout //! [`Constraint`]: ratatui_core::layout::Constraint //! [`Layout`]: ratatui_core::layout::Layout //! [`Span`]: ratatui_core::text::Span //! [`Line`]: ratatui_core::text::Line //! [`Text`]: ratatui_core::text::Text //! [`Row`]: ratatui_widgets::table::Row //! [`Cell`]: ratatui_widgets::table::Cell //! [`Table`]: ratatui_widgets::table::Table extern crate alloc; #[doc(hidden)] pub use alloc::{format, vec}; mod layout; mod line; mod row; mod span; mod text; // Re-export the core crate to use the types in macros pub use ratatui_core; ratatui-macros-0.7.0/src/line.rs000064400000000000000000000050741046102023000146550ustar 00000000000000/// A macro for creating a [`Line`] using vec! syntax. /// /// `line!` is similar to the [`vec!`] macro, but it returns a [`Line`] instead of a `Vec`. /// /// # Examples /// /// * Create a [`Line`] containing a vector of [`Span`]s: /// /// ```rust /// # use ratatui_core::style::Stylize; /// use ratatui_macros::line; /// /// let line = line!["hello", "world"]; /// let line = line!["hello".red(), "world".red().bold()]; /// ``` /// /// * Create a [`Line`] from a given [`Span`] repeated some amount of times: /// /// ```rust /// # use ratatui_macros::line; /// let line = line!["hello"; 2]; /// ``` /// /// * Use [`span!`] macro inside [`line!`] macro for formatting. /// /// ```rust /// # use ratatui_core::style::Modifier; /// use ratatui_macros::{line, span}; /// /// let line = line![span!("hello {}", "world"), span!(Modifier::BOLD; "goodbye {}", "world")]; /// ``` /// /// [`span!`]: crate::span /// [`Line`]: ratatui_core::text::Line /// [`Span`]: ratatui_core::text::Span /// [`vec!`]: alloc::vec! #[macro_export] macro_rules! line { () => { $crate::ratatui_core::text::Line::default() }; ($span:expr; $n:expr) => { $crate::ratatui_core::text::Line::from($crate::vec![$span.into(); $n]) }; ($($span:expr),+ $(,)?) => {{ $crate::ratatui_core::text::Line::from($crate::vec![ $( $span.into(), )+ ]) }}; } #[cfg(test)] mod tests { use alloc::vec; use ratatui_core::text::{Line, Span}; #[test] fn line_literal() { let line = line!["hello", "world"]; assert_eq!(line, Line::from(vec!["hello".into(), "world".into()])); } #[test] fn line_raw_instead_of_literal() { let line = line![Span::raw("hello"), "world"]; assert_eq!(line, Line::from(vec!["hello".into(), "world".into()])); } #[test] fn line_vec_count_syntax() { let line = line!["hello"; 2]; assert_eq!(line, Line::from(vec!["hello".into(), "hello".into()])); } #[test] fn line_vec_count_syntax_with_span() { let line = line![crate::span!("hello"); 2]; assert_eq!(line, Line::from(vec!["hello".into(), "hello".into()])); } #[test] fn line_empty() { let line = line![]; assert_eq!(line, Line::default()); } #[test] fn line_single_span() { let line = line![Span::raw("foo")]; assert_eq!(line, Line::from(vec!["foo".into()])); } #[test] fn line_repeated_span() { let line = line![Span::raw("foo"); 2]; assert_eq!(line, Line::from(vec!["foo".into(), "foo".into()])); } } ratatui-macros-0.7.0/src/row.rs000064400000000000000000000072741046102023000145410ustar 00000000000000/// A macro for creating a [`Row`] using vec! syntax. /// /// `row!` is similar to the [`vec!`] macro, but it returns a [`Row`] instead of a `Vec`. /// /// # Examples /// /// * Create a [`Row`] containing a vector of [`Cell`]s: /// /// ```rust /// # use ratatui_core::style::Stylize; /// use ratatui_macros::row; /// /// let row = row!["hello", "world"]; /// let row = row!["hello".red(), "world".red().bold()]; /// ``` /// /// * Create an empty [`Row`]: /// /// ```rust /// # use ratatui_macros::row; /// let empty_row = row![]; /// ``` /// /// * Create a [`Row`] from a given [`Cell`] repeated some amount of times: /// /// ```rust /// # use ratatui_macros::row; /// let row = row!["hello"; 2]; /// ``` /// /// * Use [`text!`], [`line!`] or [`span!`] macro inside [`row!`] macro. /// /// ```rust /// # use ratatui_core::style::{Modifier}; /// use ratatui_macros::{row, line, text, span}; /// /// let row = row![ /// line!["hello", "world"], span!(Modifier::BOLD; "goodbye {}", "world"), /// text!["hello", "world"], /// ]; /// ``` /// /// [`text!`]: crate::text /// [`line!`]: crate::line /// [`span!`]: crate::span /// [`row!`]: crate::row /// [`Row`]: ratatui_widgets::table::Row /// [`Cell`]: ratatui_widgets::table::Cell /// [`vec!`]: alloc::vec! #[macro_export] macro_rules! row { () => { ::ratatui_widgets::table::Row::default() }; ($cell:expr; $n:expr) => { ::ratatui_widgets::table::Row::new($crate::vec![::ratatui_widgets::table::Cell::from($cell); $n]) }; ($($cell:expr),+ $(,)?) => {{ ::ratatui_widgets::table::Row::new($crate::vec![ $( ::ratatui_widgets::table::Cell::from($cell), )+ ]) }}; } #[cfg(test)] mod tests { use alloc::vec; use ratatui_core::text::Text; use ratatui_widgets::table::{Cell, Row}; #[test] fn row_literal() { let row = row!["hello", "world"]; assert_eq!( row, Row::new(vec![Cell::from("hello"), Cell::from("world")]) ); } #[test] fn row_empty() { let row = row![]; assert_eq!(row, Row::default()); } #[test] fn row_single_cell() { let row = row![Cell::from("foo")]; assert_eq!(row, Row::new(vec![Cell::from("foo")])); } #[test] fn row_repeated_cell() { let row = row![Cell::from("foo"); 2]; assert_eq!(row, Row::new(vec![Cell::from("foo"), Cell::from("foo")])); } #[test] fn row_explicit_use_of_span_and_line() { let row = row![crate::line!("hello"), crate::span!["world"]]; assert_eq!( row, Row::new(vec![Cell::from("hello"), Cell::from("world")]) ); } #[test] fn row_vec_count_syntax() { let row = row!["hello"; 2]; assert_eq!( row, Row::new(vec![Cell::from("hello"), Cell::from("hello")]) ); } #[test] fn multiple_rows() { use crate::text; let rows = [ row!["Find File", text!["ctrl+f"].right_aligned()], row!["Open recent", text!["ctrl+r"].right_aligned()], row!["Open config", text!["ctrl+k"].right_aligned()], ]; assert_eq!( rows, [ Row::new([ Cell::from("Find File"), Cell::from(Text::raw("ctrl+f").right_aligned()), ]), Row::new([ Cell::from("Open recent"), Cell::from(Text::raw("ctrl+r").right_aligned()), ]), Row::new([ Cell::from("Open config"), Cell::from(Text::raw("ctrl+k").right_aligned()), ]), ] ); } } ratatui-macros-0.7.0/src/span.rs000064400000000000000000000175141046102023000146710ustar 00000000000000/// A macro for creating a [`Span`] using formatting syntax. /// /// `span!` is similar to the [`format!`] macro, but it returns a [`Span`] instead of a `String`. In /// addition, it also accepts an expression for the first argument, which will be converted to a /// string using the [`format!`] macro. /// /// If semicolon follows the first argument, then the first argument is a [`Style`] and a styled /// [`Span`] will be created. Otherwise, the [`Span`] will be created as a raw span (i.e. with style /// set to `Style::default()`). /// /// # Examples /// /// ```rust /// # use ratatui_core::style::{Color, Modifier, Style, Stylize}; /// use ratatui_macros::span; /// /// let content = "content"; /// /// // expression /// let span = span!(content); /// /// // format string /// let span = span!("test content"); /// let span = span!("test {}", "content"); /// let span = span!("{} {}", "test", "content"); /// let span = span!("test {content}"); /// let span = span!("test {content}", content = "content"); /// /// // with format specifiers /// let span = span!("test {:4}", 123); /// let span = span!("test {:04}", 123); /// /// let style = Style::new().green(); /// /// // styled expression /// let span = span!(style; content); /// /// // styled format string /// let span = span!(style; "test content"); /// let span = span!(style; "test {}", "content"); /// let span = span!(style; "{} {}", "test", "content"); /// let span = span!(style; "test {content}"); /// let span = span!(style; "test {content}", content = "content"); /// /// // accepts any type that is convertible to Style /// let span = span!(Style::new().green(); "test {content}"); /// let span = span!(Color::Green; "test {content}"); /// let span = span!(Modifier::BOLD; "test {content}"); /// /// // with format specifiers /// let span = span!(style; "test {:4}", 123); /// let span = span!(style; "test {:04}", 123); /// ``` /// /// # Note /// /// The first parameter must be a formatting specifier followed by a comma OR anything that can be /// converted into a [`Style`] followed by a semicolon. /// /// For example, the following will fail to compile: /// /// ```compile_fail /// # use ratatui::prelude::*; /// # use ratatui_macros::span; /// let span = span!(Modifier::BOLD, "hello world"); /// ``` /// /// But this will work: /// /// ```rust /// # use ratatui_core::style::{Modifier}; /// # use ratatui_macros::span; /// let span = span!(Modifier::BOLD; "hello world"); /// ``` /// /// The following will fail to compile: /// /// ```compile_fail /// # use ratatui::prelude::*; /// # use ratatui_macros::span; /// let span = span!("hello", "world"); /// ``` /// /// But this will work: /// /// ```rust /// # use ratatui_macros::span; /// let span = span!("hello {}", "world"); /// ``` /// /// [`Color`]: ratatui_core::style::Color /// [`Span`]: ratatui_core::text::Span /// [`Style`]: ratatui_core::style::Style /// [`format!`]: alloc::format! #[macro_export] macro_rules! span { ($string:literal) => { $crate::ratatui_core::text::Span::raw($crate::format!($string)) }; ($string:literal, $($arg:tt)*) => { $crate::ratatui_core::text::Span::raw($crate::format!($string, $($arg)*)) }; ($expr:expr) => { $crate::ratatui_core::text::Span::raw($crate::format!("{}", $expr)) }; ($style:expr, $($arg:tt)*) => { compile_error!("first parameter must be a formatting specifier followed by a comma OR a `Style` followed by a semicolon") }; ($style:expr; $string:literal) => { $crate::ratatui_core::text::Span::styled($crate::format!($string), $style) }; ($style:expr; $string:literal, $($arg:tt)*) => { $crate::ratatui_core::text::Span::styled($crate::format!($string, $($arg)*), $style) }; ($style:expr; $expr:expr) => { $crate::ratatui_core::text::Span::styled($crate::format!("{}", $expr), $style) }; } #[cfg(test)] mod tests { use ratatui_core::{ style::{Color, Modifier, Style}, text::Span, }; #[test] fn raw() { let test = "test"; let content = "content"; let number = 123; // literal let span = span!("test content"); assert_eq!(span, Span::raw("test content")); // string let span = span!("test {}", "content"); assert_eq!(span, Span::raw("test content")); // string variable let span = span!("test {}", content); assert_eq!(span, Span::raw("test content")); // string variable in the format string let span = span!("test {content}"); assert_eq!(span, Span::raw("test content")); // named variable let span = span!("test {content}", content = "content"); assert_eq!(span, Span::raw("test content")); // named variable pointing at a local variable let span = span!("test {content}", content = content); assert_eq!(span, Span::raw("test content")); // two strings let span = span!("{} {}", "test", "content"); assert_eq!(span, Span::raw("test content")); // two string variables let span = span!("{test} {content}"); assert_eq!(span, Span::raw("test content")); // a number let span = span!("test {number}"); assert_eq!(span, Span::raw("test 123")); // a number with a format specifier let span = span!("test {number:04}"); assert_eq!(span, Span::raw("test 0123")); // directly pass a number expression let span = span!(number); assert_eq!(span, Span::raw("123")); // directly pass a string expression let span = span!(test); assert_eq!(span, Span::raw("test")); } #[test] fn styled() { const STYLE: Style = Style::new().fg(Color::Green); let test = "test"; let content = "content"; let number = 123; // literal let span = span!(STYLE; "test content"); assert_eq!(span, Span::styled("test content", STYLE)); // string let span = span!(STYLE; "test {}", "content"); assert_eq!(span, Span::styled("test content", STYLE)); // string variable let span = span!(STYLE; "test {}", content); assert_eq!(span, Span::styled("test content", STYLE)); // string variable in the format string let span = span!(STYLE; "test {content}"); assert_eq!(span, Span::styled("test content", STYLE)); // named variable let span = span!(STYLE; "test {content}", content = "content"); assert_eq!(span, Span::styled("test content", STYLE)); // named variable pointing at a local variable let span = span!(STYLE; "test {content}", content = content); assert_eq!(span, Span::styled("test content", STYLE)); // two strings let span = span!(STYLE; "{} {}", "test", "content"); assert_eq!(span, Span::styled("test content", STYLE)); // two string variables let span = span!(STYLE; "{test} {content}"); assert_eq!(span, Span::styled("test content", STYLE)); // a number let span = span!(STYLE; "test {number}"); assert_eq!(span, Span::styled("test 123", STYLE)); // a number with a format specifier let span = span!(STYLE; "test {number:04}"); assert_eq!(span, Span::styled("test 0123", STYLE)); // accepts any type that is convertible to Style let span = span!(Color::Green; "test {content}"); assert_eq!(span, Span::styled("test content", STYLE)); let span = span!(Modifier::BOLD; "test {content}"); assert_eq!(span, Span::styled("test content", Style::new().bold())); // directly pass a number expression let span = span!(STYLE; number); assert_eq!(span, Span::styled("123", STYLE)); // directly pass a string expression let span = span!(STYLE; test); assert_eq!(span, Span::styled("test", STYLE)); } } ratatui-macros-0.7.0/src/text.rs000064400000000000000000000040051046102023000147030ustar 00000000000000/// A macro for creating a [`Text`] using vec! syntax. /// /// `text!` is similar to the [`vec!`] macro, but it returns a [`Text`] instead of a `Vec`. /// /// # Examples /// /// * Create a [`Text`] containing a vector of [`Line`]s: /// /// ```rust /// # use ratatui_core::style::Stylize; /// use ratatui_macros::text; /// /// let text = text!["hello", "world"]; /// let text = text!["hello".red(), "world".red().bold()]; /// ``` /// /// * Create a [`text`] from a given [`Line`] repeated some amount of times: /// /// ```rust /// # use ratatui_macros::text; /// let text = text!["hello"; 2]; /// ``` /// /// * Use [`line!`] or [`span!`] macro inside [`text!`] macro. /// /// ```rust /// # use ratatui_core::style::{Modifier}; /// use ratatui_macros::{line, text, span}; /// /// let text = text![line!["hello", "world"], span!(Modifier::BOLD; "goodbye {}", "world")]; /// ``` /// /// [`span!`]: crate::span /// [`text!`]: crate::text /// [`Text`]: ratatui_core::text::Text /// [`Line`]: ratatui_core::text::Line /// [`Span`]: ratatui_core::text::Span /// [`vec!`]: alloc::vec! #[macro_export] macro_rules! text { () => { $crate::ratatui_core::text::Text::default() }; ($line:expr; $n:expr) => { $crate::ratatui_core::text::Text::from($crate::vec![$line.into(); $n]) }; ($($line:expr),+ $(,)?) => {{ $crate::ratatui_core::text::Text::from($crate::vec![ $( $line.into(), )+ ]) }}; } #[cfg(test)] mod tests { use alloc::vec; use ratatui_core::text::Text; #[test] fn text() { // literal let text = text!["hello", "world"]; assert_eq!(text, Text::from(vec!["hello".into(), "world".into()])); // explicit use of span and line let text = text![crate::line!("hello"), crate::span!["world"]]; assert_eq!(text, Text::from(vec!["hello".into(), "world".into()])); // vec count syntax let text = text!["hello"; 2]; assert_eq!(text, Text::from(vec!["hello".into(), "hello".into()])); } } ratatui-macros-0.7.0/tests/macros.rs000064400000000000000000000061071046102023000155630ustar 00000000000000use ratatui_core::layout::{Constraint, Rect}; use ratatui_macros::{constraints, horizontal, vertical}; #[test] fn layout_constraints_macro() { let rect = Rect { x: 0, y: 0, width: 10, height: 10, }; let [rect1, rect2] = vertical![==7, <=3].split(rect).to_vec().try_into().unwrap(); assert_eq!(rect1, Rect::new(0, 0, 10, 7)); assert_eq!(rect2, Rect::new(0, 7, 10, 3)); let [rect1, rect2] = horizontal![==7, <=3] .split(rect) .to_vec() .try_into() .unwrap(); assert_eq!(rect1, Rect::new(0, 0, 7, 10)); assert_eq!(rect2, Rect::new(7, 0, 3, 10)); let one = 1; let two = 2; let ten = 10; let zero = 0; let [a, b, c, d, e, f] = horizontal![==one, >=one, <=one, == 1 / two, == ten %, >=zero] .split(rect) .to_vec() .try_into() .unwrap(); assert_eq!(a, Rect::new(0, 0, 1, 10)); assert_eq!(b, Rect::new(1, 0, 1, 10)); assert_eq!(c, Rect::new(2, 0, 1, 10)); assert_eq!(d, Rect::new(3, 0, 5, 10)); assert_eq!(e, Rect::new(8, 0, 1, 10)); assert_eq!(f, Rect::new(9, 0, 1, 10)); let one = 1; let two = 2; let ten = 10; let zero = 0; let [a, b, c, d, e, f] = horizontal![ == one*one, // expr allowed here >= one+zero, // expr allowed here <= one-zero, // expr allowed here == 1/two, // only single token allowed in numerator and denominator == ten%, // only single token allowed before % >= zero // no trailing comma ] .split(rect) .to_vec() .try_into() .unwrap(); assert_eq!(a, Rect::new(0, 0, 1, 10)); assert_eq!(b, Rect::new(1, 0, 1, 10)); assert_eq!(c, Rect::new(2, 0, 1, 10)); assert_eq!(d, Rect::new(3, 0, 5, 10)); assert_eq!(e, Rect::new(8, 0, 1, 10)); assert_eq!(f, Rect::new(9, 0, 1, 10)); let [a, b, c, d, e] = constraints![ >=0, ==1, <=5, ==10%, ==1/2 ]; assert_eq!(a, Constraint::Min(0)); assert_eq!(b, Constraint::Length(1)); assert_eq!(c, Constraint::Max(5)); assert_eq!(d, Constraint::Percentage(10)); assert_eq!(e, Constraint::Ratio(1, 2)); let [a, b, c, d, e] = constraints![ >=0; 5 ]; assert_eq!(a, Constraint::Min(0)); assert_eq!(b, Constraint::Min(0)); assert_eq!(c, Constraint::Min(0)); assert_eq!(d, Constraint::Min(0)); assert_eq!(e, Constraint::Min(0)); let [a, b, c, d, e] = constraints![ <=0; 5 ]; assert_eq!(a, Constraint::Max(0)); assert_eq!(b, Constraint::Max(0)); assert_eq!(c, Constraint::Max(0)); assert_eq!(d, Constraint::Max(0)); assert_eq!(e, Constraint::Max(0)); let [a, b] = constraints![ ==0; 2 ]; assert_eq!(a, Constraint::Length(0)); assert_eq!(b, Constraint::Length(0)); let [a, b] = constraints![ == 50%; 2 ]; assert_eq!(a, Constraint::Percentage(50)); assert_eq!(b, Constraint::Percentage(50)); let [a, b] = constraints![ == 1/2; 2 ]; assert_eq!(a, Constraint::Ratio(1, 2)); assert_eq!(b, Constraint::Ratio(1, 2)); } #[test] fn fails() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/fails.rs"); } ratatui-macros-0.7.0/tests/ui/fails.rs000064400000000000000000000007171046102023000160130ustar 00000000000000use ratatui_core::layout::Constraint; use ratatui_macros::{constraints, span}; fn main() { constraints![,]; // TODO: Make this compiler error pass let [a, b] = constraints![ == 1/2, == 2, ]; assert_eq!(a, Constraint::Ratio(1, 2)); assert_eq!(b, Constraint::Length(2)); let [a, b, c] = constraints![ == 1, == 10%, == 2; 4]; let _ = span!(Modifier::BOLD, "hello world"); let _ = span!("hello", "hello world"); } ratatui-macros-0.7.0/tests/ui/fails.stderr000064400000000000000000000037701046102023000166740ustar 00000000000000error: No rules expected the token `,` while trying to match the end of the macro --> tests/ui/fails.rs:5:5 | 5 | constraints![,]; | ^^^^^^^^^^^^^^^ | = note: this error originates in the macro `$crate::constraints` which comes from the expansion of the macro `constraints` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation --> tests/ui/fails.rs:8:18 | 8 | let [a, b] = constraints![ | __________________^ 9 | | == 1/2, 10 | | == 2, 11 | | ]; | |_____^ missing tokens in macro arguments | note: while trying to match `==` --> src/layout.rs | | (== $token:tt %) => { | ^^ = note: this error originates in the macro `$crate::constraints` which comes from the expansion of the macro `constraints` (in Nightly builds, run with -Z macro-backtrace for more info) error: no rules expected `;` --> tests/ui/fails.rs:15:53 | 15 | let [a, b, c] = constraints![ == 1, == 10%, == 2; 4]; | ^ no rules expected this token in macro call | note: while trying to match `%` --> src/layout.rs | | (== $token:tt %) => { | ^ error: first parameter must be a formatting specifier followed by a comma OR a `Style` followed by a semicolon --> tests/ui/fails.rs:17:13 | 17 | let _ = span!(Modifier::BOLD, "hello world"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `span` (in Nightly builds, run with -Z macro-backtrace for more info) error: argument never used --> tests/ui/fails.rs:19:28 | 19 | let _ = span!("hello", "hello world"); | ------- ^^^^^^^^^^^^^ argument never used | | | formatting specifier missing | help: format specifiers use curly braces, consider adding a format specifier | 19 | let _ = span!("hello{}", "hello world"); | ++