├── .gitignore ├── .idea ├── .gitignore ├── http-test │ └── http-test.json ├── modules.xml ├── untool1.iml └── vcs.xml ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── REAEME-CN.md ├── input.txt ├── output.txt └── src ├── lib.rs ├── main.rs └── utils.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.exe -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/http-test/http-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "enableAutoRestart" : false, 3 | "scanSuffix" : "java,rs,kt,go,py", 4 | "scanPath" : "", 5 | "fileSuffix" : "java,rs,kt,go,py,md,zig", 6 | "excludePath" : ".idea,.gradle,.git,node_modules,build" 7 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/untool1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.0.0 2 | - Completed the initial version build. 3 | - Implemented the functionality of converting camelCase to snake_case style. 4 | ---- 5 | ## v1.0.2 6 | - Added batch conversion functionality for variable names in files. 7 | - Created input.txt and output.txt files for testing purposes. 8 | 9 | ---- 10 | ## v1.0.4 11 | - Updated the package version to 1.0.4 in Cargo.toml and Cargo.lock. 12 | - Added repository link and documentation link. 13 | - Included homepage URL. 14 | ---- 15 | ## v1.0.5 16 | - Updated the version to 1.0.5 in Cargo.toml and Cargo.lock. 17 | - Refactored naming convention functions. 18 | - Added support for converting snake_case to camelCase. 19 | 20 | ---- 21 | ## v1.0.6 22 | - Updated dependency versions and utility functions in Cargo.toml, Cargo.lock, and source code files. 23 | - Added support for converting underscore to PascalCase. 24 | - Displayed messages with colored styles in console output. 25 | ---- 26 | 27 | ## v1.0.7 28 | - Fixed some known issues. 29 | - Perfect README and CHANGELOG 30 | - Confirmed as the first RC version 31 | --- 32 | 33 | ## v1.0.8 34 | - Added CLI function, support command line way to use untools, thanks to PR author @s4Dt0y see details [#3](https://github.com/08820048/untools/pull/3) 35 | - Fix the misspelling of the untools name in README, discovered by @SebastianJL in the Rust community 36 | - Fix README and update CHANGELOG content -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.14" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "is_terminal_polyfill", 17 | "utf8parse", 18 | ] 19 | 20 | [[package]] 21 | name = "anstyle" 22 | version = "1.0.7" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" 25 | 26 | [[package]] 27 | name = "anstyle-parse" 28 | version = "0.2.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" 31 | dependencies = [ 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle-query" 37 | version = "1.0.3" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" 40 | dependencies = [ 41 | "windows-sys", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-wincon" 46 | version = "3.0.3" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" 49 | dependencies = [ 50 | "anstyle", 51 | "windows-sys", 52 | ] 53 | 54 | [[package]] 55 | name = "clap" 56 | version = "4.5.4" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" 59 | dependencies = [ 60 | "clap_builder", 61 | "clap_derive", 62 | ] 63 | 64 | [[package]] 65 | name = "clap_builder" 66 | version = "4.5.2" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" 69 | dependencies = [ 70 | "anstream", 71 | "anstyle", 72 | "clap_lex", 73 | "strsim", 74 | ] 75 | 76 | [[package]] 77 | name = "clap_derive" 78 | version = "4.5.4" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" 81 | dependencies = [ 82 | "heck", 83 | "proc-macro2", 84 | "quote", 85 | "syn", 86 | ] 87 | 88 | [[package]] 89 | name = "clap_lex" 90 | version = "0.7.0" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" 93 | 94 | [[package]] 95 | name = "colorchoice" 96 | version = "1.0.1" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" 99 | 100 | [[package]] 101 | name = "console" 102 | version = "0.15.8" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" 105 | dependencies = [ 106 | "encode_unicode", 107 | "lazy_static", 108 | "libc", 109 | "unicode-width", 110 | "windows-sys", 111 | ] 112 | 113 | [[package]] 114 | name = "encode_unicode" 115 | version = "0.3.6" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 118 | 119 | [[package]] 120 | name = "heck" 121 | version = "0.5.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 124 | 125 | [[package]] 126 | name = "is_terminal_polyfill" 127 | version = "1.70.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" 130 | 131 | [[package]] 132 | name = "lazy_static" 133 | version = "1.4.0" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 136 | 137 | [[package]] 138 | name = "libc" 139 | version = "0.2.154" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" 142 | 143 | [[package]] 144 | name = "proc-macro2" 145 | version = "1.0.82" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" 148 | dependencies = [ 149 | "unicode-ident", 150 | ] 151 | 152 | [[package]] 153 | name = "quote" 154 | version = "1.0.36" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 157 | dependencies = [ 158 | "proc-macro2", 159 | ] 160 | 161 | [[package]] 162 | name = "strsim" 163 | version = "0.11.1" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 166 | 167 | [[package]] 168 | name = "syn" 169 | version = "2.0.63" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" 172 | dependencies = [ 173 | "proc-macro2", 174 | "quote", 175 | "unicode-ident", 176 | ] 177 | 178 | [[package]] 179 | name = "unicode-ident" 180 | version = "1.0.12" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 183 | 184 | [[package]] 185 | name = "unicode-width" 186 | version = "0.1.12" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" 189 | 190 | [[package]] 191 | name = "untools" 192 | version = "1.0.9" 193 | dependencies = [ 194 | "clap", 195 | "console", 196 | ] 197 | 198 | [[package]] 199 | name = "utf8parse" 200 | version = "0.2.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 203 | 204 | [[package]] 205 | name = "windows-sys" 206 | version = "0.52.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 209 | dependencies = [ 210 | "windows-targets", 211 | ] 212 | 213 | [[package]] 214 | name = "windows-targets" 215 | version = "0.52.5" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 218 | dependencies = [ 219 | "windows_aarch64_gnullvm", 220 | "windows_aarch64_msvc", 221 | "windows_i686_gnu", 222 | "windows_i686_gnullvm", 223 | "windows_i686_msvc", 224 | "windows_x86_64_gnu", 225 | "windows_x86_64_gnullvm", 226 | "windows_x86_64_msvc", 227 | ] 228 | 229 | [[package]] 230 | name = "windows_aarch64_gnullvm" 231 | version = "0.52.5" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 234 | 235 | [[package]] 236 | name = "windows_aarch64_msvc" 237 | version = "0.52.5" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 240 | 241 | [[package]] 242 | name = "windows_i686_gnu" 243 | version = "0.52.5" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 246 | 247 | [[package]] 248 | name = "windows_i686_gnullvm" 249 | version = "0.52.5" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 252 | 253 | [[package]] 254 | name = "windows_i686_msvc" 255 | version = "0.52.5" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 258 | 259 | [[package]] 260 | name = "windows_x86_64_gnu" 261 | version = "0.52.5" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 264 | 265 | [[package]] 266 | name = "windows_x86_64_gnullvm" 267 | version = "0.52.5" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 270 | 271 | [[package]] 272 | name = "windows_x86_64_msvc" 273 | version = "0.52.5" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 276 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "untools" 3 | version = "1.0.9" 4 | edition = "2021" 5 | authors = ["Code0408"] 6 | description = "A simple and user-friendly underscore variable naming tool." 7 | repository = "https://github.com/08820048/uutools" 8 | documentation = "https://docs.rs/untools" 9 | homepage = "https://code48.ilikexff.cn" 10 | license = "MIT" 11 | keywords = ["rust", "camelcase", "snakecase"] 12 | categories = ["development-tools"] 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | [source.crates-io] 15 | registry = "https://github.com/rust-lang/crates.io-index" 16 | 17 | replace-with = 'crates-io' 18 | [lib] 19 | name = "untools" 20 | path = "src/lib.rs" 21 | 22 | [dependencies] 23 | clap = { version = "4.5.4", features = ["derive"] } 24 | console = "0.15.8" 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Code0408 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | [中文文档](https://github.com/08820048/uutools/blob/master/REAEME-CN.md) 6 | 7 | [![Crates.io](https://img.shields.io/crates/d/untools.svg)](https://crates.io/crates/untools) 8 | [![License](https://img.shields.io/github/license/08820048/untools)](https://github.com/08820048/untools/blob/master/LICENSE) 9 | [![rustc 1.77.0](https://img.shields.io/badge/rust-1.77.0-orange.svg)](https://img.shields.io/badge/rust-1.77.0-orange.svg) 10 | [![Documentation](https://docs.rs/console/badge.svg)](https://docs.rs/untools) 11 | [![GitHub stars](https://img.shields.io/github/stars/08820048/untools)](https://github.com/08820048/untools/stargazers) 12 | [![GitHub forks](https://img.shields.io/github/forks/08820048/untools)](https://github.com/08820048/untools/network/members) 13 | [![GitHub issues](https://img.shields.io/github/issues/08820048/untools)](https://github.com/08820048/untools/issues) 14 | [![Contributors](https://img.shields.io/github/contributors/08820048/untools?style=flat-square)](https://github.com/08820048/untools/graphs/contributors) 15 | 16 | 17 | A Rust utility crate for converting variable names from `camelCase `to snake_case. 18 |
19 | 20 | ## Installation 21 | 22 | 23 | Add the following dependency to your `Cargo.toml` file: 24 | 25 | ```toml 26 | [dependencies] 27 | untools = "1.0.0" # This is just an example. It is recommended to use the latest version number. 28 | ``` 29 | 30 | ## Usage 31 | 32 | 33 | ```rust 34 | use untools::camel_to_snake; 35 | 36 | fn main() { 37 | let camel_case_name = "myVariableName"; 38 | let snake_case_name = camel_to_snake(camel_case_name, true); 39 | assert!("MY_VARIABLE_NAME', snake_case_name); 40 | } 41 | ``` 42 | 43 | ```rust 44 | use untools::batch_convert; 45 | 46 | fn main() { 47 | // Specify the input file, output file, naming convention, and whether to operate in silent mode. 48 | batch_convert("input.txt", "output.txt", true, false); 49 | } 50 | ``` 51 | 52 | In the example above: 53 | 54 | - "`input.txt`" is the path to the input file containing variable names to be converted. 55 | - "`output.txt`" is the path to the output file where the converted variable names will be written. 56 | - true indicates that the variable names will be converted to `SCREAMING_SNAKE_CASE`. Set it to false for `camelCase `conversion. 57 | - false indicates that the program will not run in silent mode. 58 | ------------------ 59 | 60 | ## CLI Usage 61 | ```shell 62 | $ untools -h 63 | Usage: untools [OPTIONS] <--camel-to-snake|--snake-to-camel|--batch > 64 | 65 | Arguments: 66 | 67 | 68 | Options: 69 | -c, --is-constant 70 | --camel-to-snake 71 | --snake-to-camel 72 | --batch 73 | -s, --silent 74 | -h, --help Print help 75 | -V, --version Print version 76 | $ untools --camel-to-snake "helloWorld" -c -s 77 | HELLO_WORLD 78 | $ untools --snake-to-camel "hello_world" -c -s 79 | HelloWorld 80 | $ untools --camel-to-snake "hello_world" -s 81 | helloWorld 82 | $ untools --batch "input.txt" "output.txt" -s 83 | ``` 84 | 85 | ## Futures 86 | 87 | > Here are the features and improvements we plan to add to the tool in the future. If you have any suggestions or ideas, feel free to share! 88 | 89 | 1. **Support for Multiple Naming Conventions:** 90 | - Add support for other naming conventions such as `SCREAMING_SNAKE_CASE`. 91 | 2. **Batch Conversion Feature:** 92 | - :white_check_mark: Allow users to convert multiple variable names at once. 93 | 3. **Interactive Mode:** 94 | - :white_check_mark: Create an interactive command-line interface for a more intuitive user experience. [#3](https://github.com/08820048/untools/pull/3) 95 | 4. **File Processing Feature:** 96 | - :white_check_mark: Support batch conversion of variable names in files. 97 | 5. **Custom Rules:** 98 | - Enable users to define custom conversion rules. 99 | 6. **Integration with Editor Plugins:** 100 | - Develop editor `plugins `to allow users to use the conversion tool directly in their editors. 101 | 7. **GUI Interface:** 102 | - Develop a graphical user interface for a more user-friendly experience. 103 | 8. **Support reverse conversion** 104 | - :white_check_mark: Convert underscores to `PascalCase `. 105 | 106 | If you have any ideas or suggestions regarding the above features, feel free to raise them in the Issues section or directly submit a Pull Request. 107 | 108 | ---- 109 | 110 | ## License 111 | 112 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/08820048/untools/blob/master/LICENSE) file for details. 113 | 114 | ---- 115 | 116 | ## Star趋势图 117 | [![Stargazers over time](https://starchart.cc/08820048/untools.svg?variant=adaptive)](https://starchart.cc/08820048/untools) 118 | -------------------------------------------------------------------------------- /REAEME-CN.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | [English](https://github.com/08820048/untools/blob/master/README.md) 7 | 8 | [![Crates.io](https://img.shields.io/crates/d/untools.svg)](https://crates.io/crates/untools) 9 | [![License](https://img.shields.io/github/license/08820048/untools)](https://github.com/08820048/untools/blob/master/LICENSE) 10 | [![rustc 1.77.0](https://img.shields.io/badge/rust-1.77.0-orange.svg)](https://img.shields.io/badge/rust-1.77.0-orange.svg) 11 | [![Documentation](https://docs.rs/console/badge.svg)](https://docs.rs/untools) 12 | [![GitHub stars](https://img.shields.io/github/stars/08820048/untools)](https://github.com/08820048/untools/stargazers) 13 | [![GitHub forks](https://img.shields.io/github/forks/08820048/untools)](https://github.com/08820048/untools/network/members) 14 | [![GitHub issues](https://img.shields.io/github/issues/08820048/untools)](https://github.com/08820048/untools/issues) 15 | [![Contributors](https://img.shields.io/github/contributors/08820048/untools?style=flat-square)](https://github.com/08820048/untools/graphs/contributors) 16 | 17 | 18 | 一个用于将变量名从驼峰式命名转换为蛇形命名的 Rust 实用工具包。 19 |
20 | 21 | 22 | ## 安装 23 | 24 | 将以下依赖项添加到您的 `Cargo.toml` 文件中: 25 | 26 | ```toml 27 | [dependencies] 28 | untools = "1.0.0" # 这只是个示例,建议使用最新的版本号 29 | ``` 30 | 31 | ## 使用 32 | 33 | ```rust 34 | use untools::camel_to_snake; 35 | 36 | fn main() { 37 | let camel_case_name = "myVariableName"; 38 | let snake_case_name = camel_to_snake(camel_case_name, true); 39 | println!("转换后的名称: {}", snake_case_name); 40 | } 41 | ``` 42 | 43 | ```rust 44 | use untools::batch_convert; 45 | fn main() { 46 | // Specify the input file, output file, and naming convention 47 | batch_convert("input.txt", "output.txt", true); 48 | } 49 | ``` 50 | 51 | - "`input.txt`" 是包含待转换变量名的输入文件路径。 52 | - "`output.txt`" 是转换后的变量名将被写入的输出文件路径。 53 | - `true `表示变量名将被转换为 `SCREAMING_SNAKE_CASE`。将其设置为 `false `可进行 `camelCase `转换。 54 | 55 | ------------------ 56 | 57 | ## CLI 的使用 58 | ```shell 59 | $ untools -h 60 | Usage: untools [OPTIONS] <--camel-to-snake|--snake-to-camel|--batch > 61 | 62 | Arguments: 63 | 64 | 65 | Options: 66 | -c, --is-constant 67 | --camel-to-snake 68 | --snake-to-camel 69 | --batch 70 | -s, --silent 71 | -h, --help Print help 72 | -V, --version Print version 73 | $ untools --camel-to-snake "helloWorld" -c -s 74 | HELLO_WORLD 75 | $ untools --snake-to-camel "hello_world" -c -s 76 | HelloWorld 77 | $ untools --camel-to-snake "hello_world" -s 78 | helloWorld 79 | $ untools --batch "input.txt" "output.txt" -s 80 | ``` 81 | 82 | ## 未来计划 83 | 84 | > 以下是我们计划在未来为工具添加的功能和改进。如果您有任何建议或想法,请随时分享! 85 | 86 | 1. **支持多种命名约定:** 87 | - 添加对其他命名约定(如 SCREAMING_SNAKE_CASE)的支持。 88 | 2. **批量转换功能:** 89 | - :white_check_mark: 允许用户一次转换多个变量名。 90 | 3. **交互模式:** 91 | - :white_check_mark: 创建交互式命令行界面,提供更直观的用户体验。[#3](https://github.com/08820048/untools/pull/3) 92 | 4. **文件处理功能:** 93 | - :white_check_mark: 支持对文件中变量名的批量转换。 94 | 5. **自定义规则:** 95 | - 允许用户定义自定义转换规则。 96 | 6. **与编辑器插件集成:** 97 | - 开发编辑器插件,使用户可以直接在其编辑器中使用转换工具。 98 | 7. **GUI界面:** 99 | - 开发图形用户界面,提供更友好的体验。 100 | 8. **支持逆向转换** 101 | - :white_check_mark: 将下划线转为大小驼峰风格 102 | 103 | 如果您对以上功能有任何想法或建议,请在`Issues`部分提出,或直接提交`Pull Request`。 104 | 105 | ---- 106 | 107 | ## 许可证 108 | 109 | 本项目根据 MIT 许可证授权 - 有关详细信息,请参阅 [LICENSE](https://github.com/08820048/untools/blob/master/LICENSE) 文件。 110 | 111 | -------------------------------------------------------------------------------- /input.txt: -------------------------------------------------------------------------------- 1 | myVariableName 2 | anotherVariable 3 | someVariableName 4 | exampleVariableName 5 | testVariable 6 | -------------------------------------------------------------------------------- /output.txt: -------------------------------------------------------------------------------- 1 | my_variable_name 2 | another_variable 3 | some_variable_name 4 | example_variable_name 5 | test_variable -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use console::style; 4 | use utils::{is_camel_or_pascal_case, starts_with_digit}; 5 | 6 | mod utils; 7 | /// Converts a camelCase or PascalCase string to snake_case. 8 | /// 9 | /// If the input string is empty, returns an error message. 10 | /// If the input string is a digit, returns an error message. 11 | /// If the input string already contains underscores, returns the input string as-is. 12 | /// If the input string is not in camelCase format, returns an error message. 13 | /// 14 | /// # Arguments 15 | /// 16 | /// * `name` - A string slice that holds the variable name to be converted. 17 | /// * `is_constant` - A boolean flag indicating if the output should be in all caps. 18 | /// 19 | /// # Returns 20 | /// 21 | /// A String containing the snake_case version of the input variable name. 22 | /// 23 | /// # Usage 24 | /// 25 | /// This converts the the variable "testVariable" from camelcase to snakecase in all caps. 26 | /// 27 | /// ``` 28 | /// use untools::camel_to_snake; 29 | /// assert_eq!(camel_to_snake("testVariable", true), "TEST_VARIABLE") 30 | /// ``` 31 | /// 32 | pub fn camel_to_snake(name: &str, is_constant: bool) -> String { 33 | if name.is_empty() { 34 | println!( 35 | "{}", 36 | style("Input string is empty. Please provide a valid variable name.").color256(208) 37 | ); 38 | return String::new(); 39 | } 40 | 41 | if !starts_with_digit(name) { 42 | println!("{}", style("Input string is a digit.").color256(208)); 43 | return String::new(); 44 | } 45 | 46 | if name.contains('_') { 47 | return name.to_string(); 48 | } 49 | 50 | if !is_camel_or_pascal_case(name) { 51 | println!( 52 | "{}", 53 | style("is not in camelCase format. Please provide a valid camelCase variable name.") 54 | .color256(208) 55 | ); 56 | return String::new(); 57 | } 58 | 59 | let mut result = String::new(); 60 | 61 | for (i, c) in name.chars().enumerate() { 62 | if i > 0 && c.is_uppercase() { 63 | result.push('_'); 64 | } 65 | result.push(c.to_lowercase().next().unwrap()); 66 | } 67 | 68 | if is_constant { 69 | return result.to_uppercase(); 70 | } 71 | 72 | result 73 | } 74 | 75 | /// Batch convert variable names 76 | /// 77 | /// This function reads variable name data from the specified input file, converts them to the specified naming convention (camelCase or SCREAMING_SNAKE_CASE), 78 | /// and then writes the converted results to the specified output file. 79 | /// 80 | /// # Arguments 81 | /// - `ifile`: The path to the input file 82 | /// - `ofile`: The path to the output file 83 | /// - `is_constant`: Whether to convert to SCREAMING_SNAKE_CASE, `true` to convert to SCREAMING_SNAKE_CASE, `false` to convert to camelCase 84 | /// - `silent`: Whether to supress output 85 | /// # Example 86 | /// 87 | /// ```rust 88 | /// untools::batch_convert("input.txt", "output.txt", true, false); 89 | /// ``` 90 | pub fn batch_convert(ifile: &str, ofile: &str, is_constant: bool, silent: bool) { 91 | let contents = fs::read_to_string(ifile).expect("Unable to read file."); 92 | 93 | let converted_names: Vec = contents 94 | .lines() 95 | .map(|line| camel_to_snake(line.trim(), is_constant)) 96 | .collect(); 97 | 98 | let output_content = converted_names.join("\n"); 99 | fs::write(ofile, output_content).expect("Unable to write file."); 100 | if !silent { 101 | println!("Batch conversion successful! Results written to {}", ofile); 102 | } 103 | } 104 | 105 | /// Converts a snake_case string to a camelCase string. 106 | /// 107 | /// # Arguments 108 | /// 109 | /// * `name` - A string slice that holds the snake_case variable name to be converted. 110 | /// * `to_lower_camel` - A boolean indicating whether the output should be in lowerCamelCase (true) or UpperCamelCase (false). 111 | /// 112 | /// # Returns 113 | /// 114 | /// * A String containing the camelCase representation of the input string. 115 | /// 116 | pub fn snake_to_camel(name: &str, upper_case_camel: bool) -> String { 117 | let mut camel_case = String::new(); 118 | let mut capitalize_next = true; 119 | 120 | let mut to_lower_camel = !upper_case_camel; 121 | 122 | if name.is_empty() { 123 | return String::from("Input string is empty. Please provide a valid variable name."); 124 | } 125 | 126 | if !starts_with_digit(name) { 127 | return String::from("Input string is a digit."); 128 | } 129 | 130 | for c in name.chars() { 131 | if c == '_' { 132 | capitalize_next = true; 133 | } else { 134 | if capitalize_next { 135 | if to_lower_camel { 136 | camel_case.push(c.to_ascii_lowercase()); 137 | to_lower_camel = false; // Reset to_lower_camel for the next word 138 | } else { 139 | camel_case.push(c.to_ascii_uppercase()); 140 | } 141 | capitalize_next = false; 142 | } else { 143 | camel_case.push(c); 144 | } 145 | } 146 | } 147 | camel_case 148 | } 149 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //! # uutols crate 2 | //! A simple and user-friendly underscore variable naming tool 3 | use std::io; 4 | use untools::{camel_to_snake, snake_to_camel, batch_convert}; 5 | use clap::{Parser, Args}; 6 | 7 | /// Command line arguments structure. 8 | #[derive(Parser, Debug)] 9 | #[command(version, about, long_about = None)] 10 | #[command(arg_required_else_help(true))] 11 | struct Cli { 12 | input: String, 13 | 14 | #[arg(long, short = 'c')] 15 | is_constant: bool, 16 | 17 | #[command(flatten)] 18 | conversion_type: ConversionType, 19 | 20 | #[arg(long, short = 's')] 21 | silent: bool 22 | } 23 | 24 | /// Structure defining the conversion type options. 25 | #[derive(Args, Debug, Clone)] 26 | #[group(required = true, multiple = false)] 27 | struct ConversionType { 28 | #[arg(long)] 29 | camel_to_snake: bool, 30 | 31 | #[arg(long)] 32 | snake_to_camel: bool, 33 | 34 | #[arg(long, value_name = "OUTPUT_FILE")] 35 | batch: Option, 36 | } 37 | 38 | /// Main function to parse command line arguments and execute the appropriate conversion. 39 | fn main() -> io::Result<()> { 40 | let args = Cli::parse(); 41 | 42 | let input = args.input; 43 | 44 | let is_constant = args.is_constant; 45 | let silent = args.silent; 46 | 47 | let conversion_type = args.conversion_type; 48 | let (cts, stc, b) = (conversion_type.camel_to_snake, conversion_type.snake_to_camel, conversion_type.batch); 49 | 50 | let mut result: Option = None; 51 | match (cts, stc, b) { 52 | (true, _, _) => { result = Some(camel_to_snake(input.as_str(), is_constant)); } 53 | 54 | (_, true, _) => { result = Some(snake_to_camel(input.as_str(), is_constant))}, 55 | 56 | (_, _, Some(output_file)) => { batch_convert(input.as_str(), output_file.as_str(), is_constant, silent) }, 57 | 58 | _ => { unreachable!() } 59 | } 60 | 61 | if !silent { 62 | println!("Output: "); 63 | } 64 | 65 | if cts || stc { 66 | if result.is_some() { 67 | println!("{}", result.unwrap()); 68 | } 69 | } 70 | 71 | println!("\nCompleted!"); 72 | 73 | Ok(()) 74 | } -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | /// Checks if a string is in camelCase or PascalCase format. 4 | /// 5 | /// # Arguments 6 | /// 7 | /// * `name` - A string slice that holds the variable name to be checked. 8 | /// 9 | /// # Returns 10 | /// 11 | /// A boolean indicating whether the input string is in camelCase or PascalCase format. 12 | /// 13 | pub(crate) fn is_camel_or_pascal_case(name: &str) -> bool { 14 | let mut has_uppercase = false; 15 | let mut has_lowercase = false; 16 | 17 | let mut chars = name.chars().peekable(); 18 | 19 | if let Some(first_char) = chars.peek() { 20 | if first_char.is_lowercase() { 21 | has_lowercase = true; 22 | } else if first_char.is_uppercase() { 23 | has_uppercase = true; 24 | } 25 | } 26 | 27 | while let Some(c) = chars.next() { 28 | if c.is_uppercase() { 29 | has_uppercase = true; 30 | } else if c.is_lowercase() { 31 | has_lowercase = true; 32 | } else if c.is_whitespace() || c == '_' { 33 | // Ignore whitespaces and underscores 34 | continue; 35 | } 36 | } 37 | 38 | has_uppercase && has_lowercase 39 | } 40 | 41 | /// Checks if a string starts with a digit. 42 | /// 43 | /// # Arguments 44 | /// 45 | /// * `name` - A string slice that holds the variable name to be checked. 46 | /// 47 | /// # Returns 48 | /// 49 | /// A boolean indicating whether the input string starts with a digit. 50 | /// 51 | pub(crate) fn starts_with_digit(name: &str) -> bool { 52 | if let Some(first_char) = name.chars().next() { 53 | if first_char.is_ascii_digit() { 54 | return false; 55 | } 56 | } 57 | true 58 | } 59 | --------------------------------------------------------------------------------