From 6d1c7d6bc0ba82cd1b7ec125f9c5b55d4c207dbe Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 16 Oct 2024 15:50:48 +0300 Subject: [PATCH 1/4] refactor: Deconflate string var from str/String types --- src/lib.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 32d8966..ec76b39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,8 +25,8 @@ pub mod python; pub mod wasm; /// Convert a string to title case following typesetting conventions for a target locale -pub fn to_titlecase(string: &str, locale: InputLocale, style: Option) -> String { - let words: Vec<&str> = string.split_whitespace().collect(); +pub fn to_titlecase(s: &str, locale: InputLocale, style: Option) -> String { + let words: Vec<&str> = s.split_whitespace().collect(); match locale { InputLocale::EN => to_titlecase_en(words, style), InputLocale::TR => to_titlecase_tr(words, style), @@ -34,8 +34,8 @@ pub fn to_titlecase(string: &str, locale: InputLocale, style: Option } /// Convert a string to lower case following typesetting conventions for a target locale -pub fn to_lowercase(string: &str, locale: InputLocale) -> String { - let words: Vec<&str> = string.split_whitespace().collect(); +pub fn to_lowercase(s: &str, locale: InputLocale) -> String { + let words: Vec<&str> = s.split_whitespace().collect(); match locale { InputLocale::EN => to_lowercase_en(words), InputLocale::TR => to_lowercase_tr(words), @@ -43,8 +43,8 @@ pub fn to_lowercase(string: &str, locale: InputLocale) -> String { } /// Convert a string to upper case following typesetting conventions for a target locale -pub fn to_uppercase(string: &str, locale: InputLocale) -> String { - let words: Vec<&str> = string.split_whitespace().collect(); +pub fn to_uppercase(s: &str, locale: InputLocale) -> String { + let words: Vec<&str> = s.split_whitespace().collect(); match locale { InputLocale::EN => to_uppercase_en(words), InputLocale::TR => to_uppercase_tr(words), @@ -52,8 +52,8 @@ pub fn to_uppercase(string: &str, locale: InputLocale) -> String { } /// Convert a string to sentence case following typesetting conventions for a target locale -pub fn to_sentencecase(string: &str, locale: InputLocale) -> String { - let words: Vec<&str> = string.split_whitespace().collect(); +pub fn to_sentencecase(s: &str, locale: InputLocale) -> String { + let words: Vec<&str> = s.split_whitespace().collect(); match locale { InputLocale::EN => to_sentencecase_en(words), InputLocale::TR => to_sentencecase_tr(words), From bf2ab4d9485c0268f7196a73a96efb3b4661c832 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Thu, 17 Oct 2024 13:43:38 +0300 Subject: [PATCH 2/4] chore(deps): Bump pinned versions of patch level crate updates --- Cargo.lock | 337 ++++++++++++++++++++++------------------------------- 1 file changed, 140 insertions(+), 197 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 734207f..71f3807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,10 +3,10 @@ version = 3 [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arc-swap" @@ -114,9 +114,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -143,9 +143,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -175,9 +175,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.10" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -187,9 +190,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.15" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -197,9 +200,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -210,18 +213,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.16" +version = "4.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c677cd0126f3026d8b093fa29eae5d812fde5c05bc66dbb29d0374eea95113a" +checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -237,9 +240,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clap_mangen" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb" +checksum = "fbae9cbfdc5d4fa8711c09bd7b83f644cb48281ac35bf97af3e47b0675864bdf" dependencies = [ "clap", "roff", @@ -331,15 +334,15 @@ checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -349,9 +352,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -492,9 +495,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.7" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b328997d74dd15dc71b2773b162cb4af9a25c424105e4876e6d0686ab41c383e" +checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c" dependencies = [ "bitflags", "bstr", @@ -564,9 +567,9 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6adf99c27cdf17b1c4d77680c917e0d94d8783d4e1c73d3be0d1d63107163d7a" +checksum = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575" dependencies = [ "fastrand", "gix-features", @@ -575,9 +578,9 @@ dependencies = [ [[package]] name = "gix-glob" -version = "0.16.4" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7df15afa265cc8abe92813cd354d522f1ac06b29ec6dfa163ad320575cb447" +checksum = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111" dependencies = [ "bitflags", "bstr", @@ -715,9 +718,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.9" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" +checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" dependencies = [ "bstr", "gix-trace", @@ -806,9 +809,9 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1547d26fa5693a7f34f05b4a3b59a90890972922172653bcb891ab3f09f436df" +checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f" dependencies = [ "bitflags", "gix-path", @@ -818,9 +821,9 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "14.0.1" +version = "14.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006acf5a613e0b5cf095d8e4b3f48c12a60d9062aa2b2dd105afaf8344a5600c" +checksum = "046b4927969fa816a150a0cda2e62c80016fe11fb3c3184e4dddf4e542f108aa" dependencies = [ "gix-fs", "libc", @@ -833,9 +836,9 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" +checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" [[package]] name = "gix-traverse" @@ -856,9 +859,9 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.27.4" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2eb9b35bba92ea8f0b5ab406fad3cf6b87f7929aa677ff10aa042c6da621156" +checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" dependencies = [ "bstr", "gix-features", @@ -943,9 +946,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" [[package]] name = "libredox" @@ -988,9 +991,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -1006,11 +1009,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1029,9 +1032,9 @@ dependencies = [ [[package]] name = "mlua-sys" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab7a5b4756b8177a2dfa8e0bbcde63bd4000afbc4ab20cbb68d114a25470f29" +checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8" dependencies = [ "cc", "cfg-if", @@ -1081,9 +1084,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "parking_lot" @@ -1105,7 +1108,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1116,15 +1119,15 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "powerfmt" @@ -1164,9 +1167,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -1179,9 +1182,9 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" [[package]] name = "pyo3" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831e8e819a138c36e212f3af3fd9eeffed6bf1510a805af35b0edee5ffa59433" +checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51" dependencies = [ "cfg-if", "indoc", @@ -1197,9 +1200,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8730e591b14492a8945cdff32f089250b05f5accecf74aeddf9e8272ce1fa8" +checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179" dependencies = [ "once_cell", "target-lexicon", @@ -1207,9 +1210,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e97e919d2df92eb88ca80a037969f44e5e70356559654962cbb3316d00300c6" +checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d" dependencies = [ "libc", "pyo3-build-config", @@ -1217,9 +1220,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb57983022ad41f9e683a599f2fd13c3664d7063a3ac5714cae4b7bee7d3f206" +checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1229,9 +1232,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec480c0c51ddec81019531705acac51bcdbeae563557c982aa8263bb96880372" +checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce" dependencies = [ "heck", "proc-macro2", @@ -1242,27 +1245,27 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1272,9 +1275,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1283,9 +1286,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "roff" @@ -1301,9 +1304,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -1314,9 +1317,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -1350,18 +1353,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.207" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1370,9 +1373,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -1386,6 +1389,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.17" @@ -1438,9 +1447,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -1455,9 +1464,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", @@ -1468,12 +1477,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -1484,18 +1493,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -1561,9 +1570,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-bom" @@ -1573,24 +1582,24 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode_titlecase" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9f865ed539c93628813817ee7076cc4d636081e35c2a9ef70626c1ef853df34" +checksum = "8f38c16011df3a49175fa6d2aba98ce0de46dc8fbad136a4e34ab02d8613f844" [[package]] name = "unindent" @@ -1657,9 +1666,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -1668,9 +1677,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -1683,9 +1692,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1693,9 +1702,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -1706,9 +1715,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "winapi-util" @@ -1719,22 +1728,13 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1743,22 +1743,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1767,46 +1752,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1819,48 +1786,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1869,9 +1812,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] From 712e350748b9bcc905f6a53b4447892d7b2fae63 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Thu, 17 Oct 2024 21:39:37 +0300 Subject: [PATCH 3/4] test: Add tests for whitespace preservation --- src/lib.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ec76b39..9d5f68b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -273,6 +273,14 @@ mod tests { "Q&A With Steve Jobs: 'That's What Happens in Technology'" ); + titlecase!( + ws_gruber, + InputLocale::EN, + Some(StyleGuide::DaringFireball), + " free trolling\n space ", + " Free Trolling\n Space " + ); + titlecase!( turkish_question, InputLocale::TR, @@ -305,6 +313,14 @@ mod tests { "Sen ve Ben ile O" ); + titlecase!( + turkish_ws, + InputLocale::TR, + None, + " serbest serseri\n boşluk ", + " Serbest Serseri\n Boşluk " + ); + macro_rules! lowercase { ($name:ident, $locale:expr, $input:expr, $expected:expr) => { #[test] From 90cc5ccb7697c30cd9de843783cbd7b6606613a5 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 16 Oct 2024 15:48:21 +0300 Subject: [PATCH 4/4] feat: Preserve whitespace from inputs --- Makefile.am | 2 +- src/bin/decasify.rs | 31 ++---- src/content.rs | 80 +++++++++++++++ src/lib.rs | 237 ++++++++++++++++++++++++++------------------ src/types.rs | 20 ++-- 5 files changed, 243 insertions(+), 127 deletions(-) create mode 100644 src/content.rs diff --git a/Makefile.am b/Makefile.am index 2004d2e..0329dab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ docdir = $(datarootdir)/doc/$(TRANSFORMED_PACKAGE_NAME) licensedir = $(datarootdir)/licenses/$(TRANSFORMED_PACKAGE_NAME) bin_PROGRAMS = decasify -decasify_SOURCES = src/bin/decasify.rs src/cli.rs src/lib.rs src/lua.rs src/python.rs src/types.rs src/wasm.rs +decasify_SOURCES = src/bin/decasify.rs src/content.rs src/cli.rs src/lib.rs src/lua.rs src/python.rs src/types.rs src/wasm.rs EXTRA_decasify_SOURCES = tests/cli.rs EXTRA_DIST = pyproject.toml spec/decasify_spec.lua tests/test_all.py dist_doc_DATA = README.md CHANGELOG.md diff --git a/src/bin/decasify.rs b/src/bin/decasify.rs index 6c99a5e..5c35dc1 100644 --- a/src/bin/decasify.rs +++ b/src/bin/decasify.rs @@ -13,7 +13,7 @@ fn main() -> Result<()> { let version = option_env!("VERGEN_GIT_DESCRIBE").unwrap_or_else(|| env!("CARGO_PKG_VERSION")); let app = Cli::command().version(version); let matches = app.get_matches(); - let locale = matches.get_one::("locale").unwrap().to_owned(); + let locale = matches.get_one::("locale").unwrap(); let case = matches.get_one::("case").unwrap().to_owned(); let style = matches.get_one::("style").map(|s| s.to_owned()); match matches.contains_id("input") { @@ -24,11 +24,11 @@ fn main() -> Result<()> { .cloned() .collect(); let input: Vec = vec![input.join(" ")]; - process(input.iter().map(|ln| ln.to_string()), locale, case, style); + process(input.iter().map(|ln| ln.to_string()), *locale, case, style); } false => process( io::stdin().lock().lines().map(|ln| ln.unwrap()), - locale, + *locale, case, style, ), @@ -43,23 +43,12 @@ fn process>( style: Option, ) { for string in strings { - match case { - TargetCase::Title => { - let output = to_titlecase(&string, locale.clone(), style.clone()); - println!("{output}") - } - TargetCase::Lower => { - let output = to_lowercase(&string, locale.clone()); - println!("{output}") - } - TargetCase::Upper => { - let output = to_uppercase(&string, locale.clone()); - println!("{output}") - } - TargetCase::Sentence => { - let output = to_sentencecase(&string, locale.clone()); - println!("{output}") - } - } + let output = match case { + TargetCase::Title => to_titlecase(string, locale, style), + TargetCase::Lower => to_lowercase(string, locale), + TargetCase::Upper => to_uppercase(string, locale), + TargetCase::Sentence => to_sentencecase(string, locale), + }; + println!("{output}") } } diff --git a/src/content.rs b/src/content.rs new file mode 100644 index 0000000..217763d --- /dev/null +++ b/src/content.rs @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: © 2023 Caleb Maclennan +// SPDX-License-Identifier: LGPL-3.0-only + +use crate::types::Result; +use regex::Regex; +use std::{borrow::Cow, error, fmt, fmt::Display, str::FromStr}; + +#[derive(Clone, Debug, PartialEq)] +pub enum Segment { + Separator(String), + Word(String), +} + +#[derive(Debug, Clone)] +pub struct Chunk { + pub segments: Vec, +} + +fn split_chunk(src: &str) -> Chunk { + let mut segments: Vec = Vec::new(); + let captures = Regex::new(r"(?\p{Whitespace}+)|(?\P{Whitespace}+)").unwrap(); + for capture in captures.captures_iter(src) { + if let Some(m) = capture.name("separator") { + segments.push(Segment::Separator(m.as_str().to_string())); + } else if let Some(m) = capture.name("word") { + segments.push(Segment::Word(m.as_str().to_string())); + } + } + Chunk { segments } +} + +impl From for Chunk { + fn from(src: String) -> Self { + split_chunk(src.as_ref()) + } +} + +impl From<&String> for Chunk { + fn from(src: &String) -> Self { + split_chunk(src.as_ref()) + } +} + +impl From<&str> for Chunk { + fn from(src: &str) -> Self { + split_chunk(src) + } +} + +impl From<&Cow<'_, str>> for Chunk { + fn from(src: &Cow<'_, str>) -> Self { + split_chunk(src) + } +} + +impl FromStr for Chunk { + type Err = Box; + fn from_str(src: &str) -> Result { + Ok(split_chunk(src)) + } +} + +impl Display for Segment { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let _ = match self { + Segment::Separator(string) => fmt.write_str(string), + Segment::Word(string) => fmt.write_str(string), + }; + Ok(()) + } +} + +impl Display for Chunk { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + for segment in &self.segments { + fmt.write_str(segment.to_string().as_ref())?; + } + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 9d5f68b..ddbb8a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,10 @@ use titlecase::titlecase as gruber_titlecase; use unicode_titlecase::tr_az::StrTrAzCasing; use unicode_titlecase::StrTitleCase; +pub mod content; pub mod types; +pub use content::{Chunk, Segment}; pub use types::{InputLocale, Result, StyleGuide, TargetCase}; #[cfg(feature = "cli")] @@ -25,97 +27,124 @@ pub mod python; pub mod wasm; /// Convert a string to title case following typesetting conventions for a target locale -pub fn to_titlecase(s: &str, locale: InputLocale, style: Option) -> String { - let words: Vec<&str> = s.split_whitespace().collect(); +pub fn to_titlecase( + chunk: impl Into, + locale: InputLocale, + style: Option, +) -> String { + let chunk: Chunk = chunk.into(); match locale { - InputLocale::EN => to_titlecase_en(words, style), - InputLocale::TR => to_titlecase_tr(words, style), + InputLocale::EN => to_titlecase_en(chunk, style), + InputLocale::TR => to_titlecase_tr(chunk, style), } } /// Convert a string to lower case following typesetting conventions for a target locale -pub fn to_lowercase(s: &str, locale: InputLocale) -> String { - let words: Vec<&str> = s.split_whitespace().collect(); +pub fn to_lowercase(chunk: impl Into, locale: impl Into) -> String { + let chunk: Chunk = chunk.into(); + let locale: InputLocale = locale.into(); match locale { - InputLocale::EN => to_lowercase_en(words), - InputLocale::TR => to_lowercase_tr(words), + InputLocale::EN => to_lowercase_en(chunk), + InputLocale::TR => to_lowercase_tr(chunk), } } /// Convert a string to upper case following typesetting conventions for a target locale -pub fn to_uppercase(s: &str, locale: InputLocale) -> String { - let words: Vec<&str> = s.split_whitespace().collect(); +pub fn to_uppercase(chunk: impl Into, locale: impl Into) -> String { + let chunk: Chunk = chunk.into(); + let locale: InputLocale = locale.into(); match locale { - InputLocale::EN => to_uppercase_en(words), - InputLocale::TR => to_uppercase_tr(words), + InputLocale::EN => to_uppercase_en(chunk), + InputLocale::TR => to_uppercase_tr(chunk), } } /// Convert a string to sentence case following typesetting conventions for a target locale -pub fn to_sentencecase(s: &str, locale: InputLocale) -> String { - let words: Vec<&str> = s.split_whitespace().collect(); +pub fn to_sentencecase(chunk: impl Into, locale: impl Into) -> String { + let chunk: Chunk = chunk.into(); + let locale: InputLocale = locale.into(); match locale { - InputLocale::EN => to_sentencecase_en(words), - InputLocale::TR => to_sentencecase_tr(words), + InputLocale::EN => to_sentencecase_en(chunk), + InputLocale::TR => to_sentencecase_tr(chunk), } } -fn to_titlecase_en(words: Vec<&str>, style: Option) -> String { +fn to_titlecase_en(chunk: Chunk, style: Option) -> String { match style { - Some(StyleGuide::AssociatedPress) => to_titlecase_ap(words), - Some(StyleGuide::ChicagoManualOfStyle) => to_titlecase_cmos(words), - Some(StyleGuide::DaringFireball) => to_titlecase_gruber(words), - None => to_titlecase_gruber(words), + Some(StyleGuide::AssociatedPress) => to_titlecase_ap(chunk), + Some(StyleGuide::ChicagoManualOfStyle) => to_titlecase_cmos(chunk), + Some(StyleGuide::DaringFireball) => to_titlecase_gruber(chunk), + None => to_titlecase_gruber(chunk), } } -fn to_titlecase_ap(words: Vec<&str>) -> String { +fn to_titlecase_ap(chunk: Chunk) -> String { eprintln!("AP style guide not implemented, string returned as-is!"); - words.join(" ") + chunk.to_string() } -fn to_titlecase_cmos(words: Vec<&str>) -> String { - let mut words = words.iter().peekable(); - let mut output: Vec = Vec::new(); - let first = words.next().unwrap(); - output.push(first.to_titlecase_lower_rest()); - while let Some(word) = words.next() { - if words.peek().is_none() { - output.push(word.to_titlecase_lower_rest()); - } else { - match is_reserved_en(word.to_string()) { - true => output.push(word.to_string().to_lowercase()), - false => { - output.push(word.to_titlecase_lower_rest()); +fn to_titlecase_cmos(chunk: Chunk) -> String { + let mut done_first = false; + let mut chunk = chunk.clone(); + let mut segments = chunk.segments.iter_mut().peekable(); + while let Some(segment) = segments.next() { + if let Segment::Word(s) = segment { + *s = if !done_first { + done_first = true; + s.to_string().to_titlecase_lower_rest() + } else if segments.peek().is_none() { + // TODO: I think a bug is hiding here since peek() might give use a separator + // that happens to be a trailing trivia. We need a custom iterator or peeker + // that knows how to answer about first/last *word* segments. + s.to_string().to_titlecase_lower_rest() + } else { + match is_reserved_en(s.to_string()) { + true => s.to_string().to_lowercase(), + false => s.to_string().to_titlecase_lower_rest(), } } } } - output.join(" ") + chunk.to_string() } -fn to_titlecase_gruber(words: Vec<&str>) -> String { - let text = words.join(" "); - gruber_titlecase(&text) +fn to_titlecase_gruber(chunk: Chunk) -> String { + // The titlecase crate we are going to delegate to here trims the input. We need to restore + // leading and trailing whitespace ourselves. + let leading_trivia = if let Some(Segment::Separator(s)) = chunk.segments.first() { + s.to_string() + } else { + String::from("") + }; + let trailing_trivia = if let Some(Segment::Separator(s)) = chunk.segments.last() { + s.to_string() + } else { + String::from("") + }; + let titilized = gruber_titlecase(&chunk.to_string()); + format!("{}{}{}", leading_trivia, titilized, trailing_trivia) } -fn to_titlecase_tr(words: Vec<&str>, style: Option) -> String { +fn to_titlecase_tr(chunk: Chunk, style: Option) -> String { match style { - Some(_) => panic!("Turkish implementation doesn't support different style guides."), + Some(_) => todo!("Turkish implementation doesn't support different style guides."), None => { - let mut words = words.iter(); - let mut output: Vec = Vec::new(); - let first = words.next().unwrap(); - output.push(first.to_titlecase_tr_or_az_lower_rest()); - for word in words { - match is_reserved_tr(word.to_string()) { - true => output.push(word.to_string().to_lowercase_tr_az()), - false => { - output.push(word.to_titlecase_tr_or_az_lower_rest()); + let mut chunk = chunk.clone(); + let mut done_first = false; + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = if !done_first { + done_first = true; + s.to_string().to_titlecase_tr_or_az_lower_rest() + } else { + match is_reserved_tr(s.to_string()) { + true => s.to_string().to_lowercase_tr_az(), + false => s.to_titlecase_tr_or_az_lower_rest(), + } } } - } - output.join(" ") + }); + chunk.to_string() } } } @@ -139,58 +168,76 @@ fn is_reserved_tr(word: String) -> bool { baglac.is_match(word) || soruek.is_match(word) } -fn to_lowercase_en(words: Vec<&str>) -> String { - let mut output: Vec = Vec::new(); - for word in words { - output.push(word.to_lowercase()); - } - output.join(" ") +fn to_lowercase_en(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = s.to_string().to_lowercase() + } + }); + chunk.to_string() } -fn to_lowercase_tr(words: Vec<&str>) -> String { - let mut output: Vec = Vec::new(); - for word in words { - output.push(word.to_lowercase_tr_az()); - } - output.join(" ") +fn to_lowercase_tr(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = s.to_string().to_lowercase_tr_az() + } + }); + chunk.to_string() } -fn to_uppercase_en(words: Vec<&str>) -> String { - let mut output: Vec = Vec::new(); - for word in words { - output.push(word.to_uppercase()); - } - output.join(" ") +fn to_uppercase_en(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = s.to_string().to_uppercase() + } + }); + chunk.to_string() } -fn to_uppercase_tr(words: Vec<&str>) -> String { - let mut output: Vec = Vec::new(); - for word in words { - output.push(word.to_uppercase_tr_az()); - } - output.join(" ") +fn to_uppercase_tr(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = s.to_string().to_uppercase_tr_az() + } + }); + chunk.to_string() } -fn to_sentencecase_en(words: Vec<&str>) -> String { - let mut words = words.iter().peekable(); - let mut output: Vec = Vec::new(); - let first = words.next().unwrap(); - output.push(gruber_titlecase(first)); - for word in words { - output.push(word.to_lowercase()); - } - output.join(" ") +fn to_sentencecase_en(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + let mut done_first = false; + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = if !done_first { + done_first = true; + s.to_string().to_titlecase_lower_rest() + } else { + s.to_string().to_lowercase() + } + } + }); + chunk.to_string() } -fn to_sentencecase_tr(words: Vec<&str>) -> String { - let mut words = words.iter().peekable(); - let mut output: Vec = Vec::new(); - let first = words.next().unwrap(); - output.push(first.to_titlecase_tr_or_az()); - for word in words { - output.push(word.to_lowercase_tr_az()); - } - output.join(" ") +fn to_sentencecase_tr(chunk: Chunk) -> String { + let mut chunk = chunk.clone(); + let mut done_first = false; + chunk.segments.iter_mut().for_each(|segment| { + if let Segment::Word(s) = segment { + *s = if !done_first { + done_first = true; + s.to_string().to_titlecase_tr_or_az_lower_rest() + } else { + s.to_string().to_lowercase_tr_az() + } + } + }); + chunk.to_string() } #[cfg(test)] diff --git a/src/types.rs b/src/types.rs index 7ec7fff..a857740 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: © 2023 Caleb Maclennan // SPDX-License-Identifier: LGPL-3.0-only -use std::{error, fmt, result, str::FromStr}; +use std::{error, fmt, fmt::Display, result, str::FromStr}; use strum_macros::{Display, VariantNames}; #[cfg(feature = "pythonmodule")] @@ -13,18 +13,18 @@ use wasm_bindgen::prelude::*; pub type Result = result::Result>; #[derive(Debug)] -struct DecasifyError(String); +pub struct Error(pub String); -impl fmt::Display for DecasifyError { +impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } -impl error::Error for DecasifyError {} +impl error::Error for Error {} /// Locale selector to change language support rules of case functions. -#[derive(Default, Display, VariantNames, Debug, Clone, PartialEq)] +#[derive(Default, Display, VariantNames, Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "pythonmodule", pyclass(eq, eq_int))] #[cfg_attr(feature = "wasm", wasm_bindgen)] #[strum(serialize_all = "lowercase")] @@ -35,7 +35,7 @@ pub enum InputLocale { } /// Target case selector. -#[derive(Default, Display, VariantNames, Debug, Clone, PartialEq)] +#[derive(Default, Display, VariantNames, Debug, Clone, Copy, PartialEq)] #[strum(serialize_all = "lowercase")] pub enum TargetCase { Lower, @@ -46,7 +46,7 @@ pub enum TargetCase { } /// Style guide selector to change grammar and context rules used for title casing. -#[derive(Default, Display, VariantNames, Debug, Clone, PartialEq)] +#[derive(Default, Display, VariantNames, Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "pythonmodule", pyclass(eq, eq_int))] #[cfg_attr(feature = "wasm", wasm_bindgen)] #[strum(serialize_all = "lowercase")] @@ -66,7 +66,7 @@ impl FromStr for InputLocale { match s.to_ascii_lowercase().as_str() { "en" | "English" | "en_en" => Ok(InputLocale::EN), "tr" | "Turkish" | "tr_tr" | "türkçe" => Ok(InputLocale::TR), - _ => Err(Box::new(DecasifyError("Invalid input language".into()))), + _ => Err(Box::new(Error("Invalid input language".into()))), } } } @@ -79,7 +79,7 @@ impl FromStr for TargetCase { "sentence" => Ok(TargetCase::Sentence), "title" => Ok(TargetCase::Title), "upper" => Ok(TargetCase::Upper), - _ => Err(Box::new(DecasifyError("Unknown target case".into()))), + _ => Err(Box::new(Error("Unknown target case".into()))), } } } @@ -91,7 +91,7 @@ impl FromStr for StyleGuide { "daringfireball" | "gruber" | "fireball" => Ok(StyleGuide::DaringFireball), "associatedpress" | "ap" => Ok(StyleGuide::AssociatedPress), "chicagoManualofstyle" | "chicago" | "cmos" => Ok(StyleGuide::ChicagoManualOfStyle), - _ => Err(Box::new(DecasifyError("Invalid style guide".into()))), + _ => Err(Box::new(Error("Invalid style guide".into()))), } } }