From fcbd18c4b7d90388a9a2b9e28555d2526727958c Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 25 Feb 2026 15:24:18 +0800 Subject: Replace string_proc with just_fmt as external dependency --- Cargo.lock | 32 +-- Cargo.toml | 4 - legacy_actions/Cargo.toml | 3 +- legacy_data/Cargo.toml | 4 +- legacy_data/src/data/local.rs | 7 +- legacy_data/src/data/local/cached_sheet.rs | 12 +- legacy_data/src/data/local/local_files.rs | 4 +- legacy_data/src/data/local/local_sheet.rs | 27 ++- legacy_data/src/data/local/workspace_analyzer.rs | 4 +- legacy_data/src/data/local/workspace_config.rs | 2 +- legacy_data/src/data/member.rs | 2 +- legacy_data/src/data/vault/mapping_share.rs | 4 +- legacy_data/src/data/vault/sheet_manage.rs | 2 +- legacy_data/src/data/vault/virtual_file.rs | 2 +- src/lib.rs | 7 - systems/action/action_macros/Cargo.toml | 3 +- systems/action/action_macros/src/lib.rs | 4 +- utils/string_proc/Cargo.toml | 7 - utils/string_proc/src/format_path.rs | 187 ------------------ utils/string_proc/src/format_processer.rs | 242 ----------------------- utils/string_proc/src/lib.rs | 15 -- utils/string_proc/src/macros.rs | 127 ------------ utils/string_proc/src/simple_processer.rs | 15 -- 23 files changed, 55 insertions(+), 661 deletions(-) delete mode 100644 utils/string_proc/Cargo.toml delete mode 100644 utils/string_proc/src/format_path.rs delete mode 100644 utils/string_proc/src/format_processer.rs delete mode 100644 utils/string_proc/src/lib.rs delete mode 100644 utils/string_proc/src/macros.rs delete mode 100644 utils/string_proc/src/simple_processer.rs diff --git a/Cargo.lock b/Cargo.lock index 88a8d1d..291cf25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,11 +17,11 @@ dependencies = [ name = "action_system_macros" version = "0.1.0" dependencies = [ + "just_fmt", "proc-macro2", "quote", "serde", "serde_json", - "string_proc", "syn", "tcp_connection", ] @@ -798,7 +798,6 @@ dependencies = [ "jvlib", "sha1_hash", "sheet_system", - "string_proc", "tcp_connection", "toml", "vcs_actions", @@ -1566,22 +1565,6 @@ dependencies = [ "der", ] -[[package]] -name = "string_proc" -version = "0.1.0" -dependencies = [ - "strip-ansi-escapes", -] - -[[package]] -name = "strip-ansi-escapes" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" -dependencies = [ - "vte", -] - [[package]] name = "subtle" version = "2.6.1" @@ -1783,11 +1766,11 @@ version = "0.1.0" dependencies = [ "action_system", "cfg_file", + "just_fmt", "log", "serde", "serde_json", "sha1_hash", - "string_proc", "tcp_connection", "thiserror 2.0.17", "tokio", @@ -1803,10 +1786,10 @@ dependencies = [ "chrono", "data_struct", "dirs", + "just_fmt", "rand 0.9.2", "serde", "sha1_hash", - "string_proc", "tcp_connection", "tokio", "uuid", @@ -1837,15 +1820,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vte" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" -dependencies = [ - "memchr", -] - [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 67ef00c..6881a81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,14 +15,12 @@ utils = [ "hex_display", "sha1_hash", "tcp_connection", - "string_proc", ] cfg_file = [] data_struct = [] hex_display = [] sha1_hash = [] tcp_connection = [] -string_proc = [] lib = [] deprecated = [] @@ -52,7 +50,6 @@ members = [ "legacy_data", "legacy_data/tests", "legacy_actions", - "utils/string_proc", # Will be gradually migrated to `just_fmt` # LEGACY AREA ] @@ -95,7 +92,6 @@ data_struct = { path = "utils/data_struct" } hex_display = { path = "utils/hex_display" } sha1_hash = { path = "utils/sha1_hash" } tcp_connection = { path = "utils/tcp_connection" } -string_proc = { path = "utils/string_proc" } # Systems asset_system = { path = "systems/_asset" } diff --git a/legacy_actions/Cargo.toml b/legacy_actions/Cargo.toml index a49e1b0..7c9e078 100644 --- a/legacy_actions/Cargo.toml +++ b/legacy_actions/Cargo.toml @@ -9,7 +9,8 @@ version.workspace = true tcp_connection = { path = "../utils/tcp_connection" } cfg_file = { path = "../utils/cfg_file", features = ["default"] } sha1_hash = { path = "../utils/sha1_hash" } -string_proc = { path = "../utils/string_proc" } + +just_fmt = "0.1.2" # Core dependencies action_system = { path = "../systems/action" } diff --git a/legacy_data/Cargo.toml b/legacy_data/Cargo.toml index 7506814..27fe6ad 100644 --- a/legacy_data/Cargo.toml +++ b/legacy_data/Cargo.toml @@ -10,12 +10,14 @@ cfg_file = { path = "../utils/cfg_file", features = ["default"] } data_struct = { path = "../utils/data_struct" } sha1_hash = { path = "../utils/sha1_hash" } tcp_connection = { path = "../utils/tcp_connection" } -string_proc = { path = "../utils/string_proc" } # Core action_system = { path = "../systems/action" } vcs_docs = { path = "../docs" } +# Format +just_fmt = "0.1.2" + # Random rand = "0.9.2" diff --git a/legacy_data/src/data/local.rs b/legacy_data/src/data/local.rs index d4115c6..8423168 100644 --- a/legacy_data/src/data/local.rs +++ b/legacy_data/src/data/local.rs @@ -1,12 +1,13 @@ use std::{ collections::HashMap, env::current_dir, + io::ErrorKind, path::{Path, PathBuf}, sync::Arc, }; use cfg_file::config::ConfigFile; -use string_proc::format_path::format_path; +use just_fmt::fmt_path::fmt_path; use tokio::{fs, sync::Mutex}; use vcs_docs::docs::READMES_LOCAL_WORKSPACE_TODOLIST; @@ -176,7 +177,9 @@ impl LocalWorkspace { && let Some(extension) = path.extension() && extension == suffix.trim_start_matches('.') { - let formatted_path = format_path(path)?; + let formatted_path = fmt_path(path).map_err(|e| { + std::io::Error::new(ErrorKind::InvalidInput, e.to_string()) + })?; paths.push(formatted_path); } } diff --git a/legacy_data/src/data/local/cached_sheet.rs b/legacy_data/src/data/local/cached_sheet.rs index 46b390f..e67861b 100644 --- a/legacy_data/src/data/local/cached_sheet.rs +++ b/legacy_data/src/data/local/cached_sheet.rs @@ -1,7 +1,10 @@ -use std::{io::Error, path::PathBuf}; +use std::{ + io::{Error, ErrorKind}, + path::PathBuf, +}; use cfg_file::config::ConfigFile; -use string_proc::{format_path::format_path, snake_case}; +use just_fmt::{fmt_path::fmt_path, snake_case}; use tokio::fs; use crate::{ @@ -85,7 +88,10 @@ impl CachedSheet { && let Some(file_name) = path.file_name().and_then(|n| n.to_str()) && file_name.ends_with(CLIENT_SUFFIX_CACHED_SHEET_FILE) { - sheet_paths.push(format_path(workspace_path.join(path))?); + sheet_paths + .push(fmt_path(workspace_path.join(path)).map_err(|e| { + std::io::Error::new(ErrorKind::InvalidInput, e.to_string()) + })?); } } diff --git a/legacy_data/src/data/local/local_files.rs b/legacy_data/src/data/local/local_files.rs index 9cc244f..2f02b32 100644 --- a/legacy_data/src/data/local/local_files.rs +++ b/legacy_data/src/data/local/local_files.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use string_proc::format_path::format_path; +use just_fmt::fmt_path::fmt_path; use tokio::fs; use crate::constants::CLIENT_FOLDER_WORKSPACE_ROOT_NAME; @@ -59,7 +59,7 @@ async fn format_input_paths( continue; } - match format_path(path) { + match fmt_path(path) { Ok(path) => real_paths.push(path), Err(e) => { return Err(std::io::Error::new( diff --git a/legacy_data/src/data/local/local_sheet.rs b/legacy_data/src/data/local/local_sheet.rs index b9c29f5..eee0866 100644 --- a/legacy_data/src/data/local/local_sheet.rs +++ b/legacy_data/src/data/local/local_sheet.rs @@ -1,8 +1,13 @@ -use std::{collections::HashMap, io::Error, path::PathBuf, time::SystemTime}; +use std::{ + collections::HashMap, + io::{Error, ErrorKind}, + path::PathBuf, + time::SystemTime, +}; use ::serde::{Deserialize, Serialize}; use cfg_file::{ConfigFile, config::ConfigFile}; -use string_proc::format_path::format_path; +use just_fmt::fmt_path::fmt_path; use crate::{ constants::CLIENT_FILE_LOCAL_SHEET_NOSET, @@ -278,7 +283,8 @@ impl LocalSheetData { path: &LocalFilePathBuf, mapping: LocalMappingMetadata, ) -> Result<(), std::io::Error> { - let path = format_path(path)?; + let path = fmt_path(path) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; if self.mapping.contains_key(&path) || self.vfs.contains_key(&mapping.mapping_vfid) { return Err(Error::new( std::io::ErrorKind::AlreadyExists, @@ -297,8 +303,10 @@ impl LocalSheetData { from: &LocalFilePathBuf, to: &LocalFilePathBuf, ) -> Result<(), std::io::Error> { - let from = format_path(from)?; - let to = format_path(to)?; + let from = fmt_path(from) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; + let to = fmt_path(to) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; if self.mapping.contains_key(&to) { return Err(Error::new( std::io::ErrorKind::AlreadyExists, @@ -325,7 +333,8 @@ impl LocalSheetData { &mut self, path: &LocalFilePathBuf, ) -> Result { - let path = format_path(path)?; + let path = fmt_path(path) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; match self.mapping.remove(&path) { Some(mapping) => { self.vfs.remove(&mapping.mapping_vfid); @@ -343,7 +352,8 @@ impl LocalSheetData { &self, path: &LocalFilePathBuf, ) -> Result<&LocalMappingMetadata, std::io::Error> { - let path = format_path(path)?; + let path = fmt_path(path) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; let Some(data) = self.mapping.get(&path) else { return Err(Error::new( std::io::ErrorKind::NotFound, @@ -358,7 +368,8 @@ impl LocalSheetData { &mut self, path: &LocalFilePathBuf, ) -> Result<&mut LocalMappingMetadata, std::io::Error> { - let path = format_path(path)?; + let path = fmt_path(path) + .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e.to_string()))?; let Some(data) = self.mapping.get_mut(&path) else { return Err(Error::new( std::io::ErrorKind::NotFound, diff --git a/legacy_data/src/data/local/workspace_analyzer.rs b/legacy_data/src/data/local/workspace_analyzer.rs index 5d73e03..82cd4e0 100644 --- a/legacy_data/src/data/local/workspace_analyzer.rs +++ b/legacy_data/src/data/local/workspace_analyzer.rs @@ -4,9 +4,9 @@ use std::{ path::PathBuf, }; +use just_fmt::fmt_path::fmt_path; use serde::Serialize; use sha1_hash::calc_sha1_multi; -use string_proc::format_path::format_path; use walkdir::WalkDir; use crate::data::{ @@ -116,7 +116,7 @@ impl<'a> AnalyzeResult<'a> { if entry.file_type().is_file() && let Ok(relative_path) = entry.path().strip_prefix(local_path) { - let format = format_path(relative_path.to_path_buf()); + let format = fmt_path(relative_path.to_path_buf()); let Ok(format) = format else { continue; }; diff --git a/legacy_data/src/data/local/workspace_config.rs b/legacy_data/src/data/local/workspace_config.rs index f97d049..fc63e9c 100644 --- a/legacy_data/src/data/local/workspace_config.rs +++ b/legacy_data/src/data/local/workspace_config.rs @@ -1,11 +1,11 @@ use cfg_file::ConfigFile; use cfg_file::config::ConfigFile; +use just_fmt::snake_case; use serde::{Deserialize, Serialize}; use std::io::Error; use std::net::SocketAddr; use std::path::Path; use std::path::PathBuf; -use string_proc::snake_case; use crate::constants::CLIENT_FILE_WORKSPACE; use crate::constants::CLIENT_FOLDER_WORKSPACE_ROOT_NAME; diff --git a/legacy_data/src/data/member.rs b/legacy_data/src/data/member.rs index 7e99488..bcfa9bf 100644 --- a/legacy_data/src/data/member.rs +++ b/legacy_data/src/data/member.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use cfg_file::ConfigFile; +use just_fmt::snake_case; use serde::{Deserialize, Serialize}; -use string_proc::snake_case; pub type MemberId = String; diff --git a/legacy_data/src/data/vault/mapping_share.rs b/legacy_data/src/data/vault/mapping_share.rs index 5d27859..59cd6ba 100644 --- a/legacy_data/src/data/vault/mapping_share.rs +++ b/legacy_data/src/data/vault/mapping_share.rs @@ -1,9 +1,9 @@ use std::{collections::HashMap, io::Error, path::PathBuf}; use cfg_file::{ConfigFile, config::ConfigFile}; +use just_fmt::{fmt_path::fmt_path_str, snake_case}; use rand::{Rng, rng}; use serde::{Deserialize, Serialize}; -use string_proc::{format_path, snake_case}; use tokio::fs; use crate::{ @@ -89,7 +89,7 @@ impl Vault { .replace(KEY_SHARE_ID, &share_id); // Use format_path to normalize the path - match format_path::format_path_str(&path_str) { + match fmt_path_str(&path_str) { Ok(normalized_path) => self.vault_path().join(normalized_path), Err(_) => { // Fallback to original behavior if formatting fails diff --git a/legacy_data/src/data/vault/sheet_manage.rs b/legacy_data/src/data/vault/sheet_manage.rs index c22c849..70fef88 100644 --- a/legacy_data/src/data/vault/sheet_manage.rs +++ b/legacy_data/src/data/vault/sheet_manage.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, io::Error}; use cfg_file::config::ConfigFile; -use string_proc::snake_case; +use just_fmt::snake_case; use tokio::fs; use crate::{ diff --git a/legacy_data/src/data/vault/virtual_file.rs b/legacy_data/src/data/vault/virtual_file.rs index 28e9172..06ec3f4 100644 --- a/legacy_data/src/data/vault/virtual_file.rs +++ b/legacy_data/src/data/vault/virtual_file.rs @@ -5,8 +5,8 @@ use std::{ }; use cfg_file::{ConfigFile, config::ConfigFile}; +use just_fmt::{dot_case, snake_case}; use serde::{Deserialize, Serialize}; -use string_proc::{dot_case, snake_case}; use tcp_connection::instance::ConnectionInstance; use tokio::fs; use uuid::Uuid; diff --git a/src/lib.rs b/src/lib.rs index 7d05c3e..48decb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,11 +68,4 @@ pub mod utils { extern crate tcp_connection; pub use tcp_connection::*; } - - // Feature `string_proc` - #[cfg(all(feature = "deprecated", feature = "string_proc"))] - pub mod string_proc { - extern crate string_proc; - pub use string_proc::*; - } } diff --git a/systems/action/action_macros/Cargo.toml b/systems/action/action_macros/Cargo.toml index 8b23191..0f209e2 100644 --- a/systems/action/action_macros/Cargo.toml +++ b/systems/action/action_macros/Cargo.toml @@ -8,7 +8,8 @@ proc-macro = true [dependencies] tcp_connection = { path = "../../../utils/tcp_connection" } -string_proc = { path = "../../../utils/string_proc" } + +just_fmt = "0.1.2" syn = { version = "2.0", features = ["full", "extra-traits"] } quote = "1.0" diff --git a/systems/action/action_macros/src/lib.rs b/systems/action/action_macros/src/lib.rs index e6616b4..6da0339 100644 --- a/systems/action/action_macros/src/lib.rs +++ b/systems/action/action_macros/src/lib.rs @@ -89,7 +89,7 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok impl action_system::action::Action<#arg_type, #return_type> for #struct_name { fn action_name() -> &'static str { - Box::leak(string_proc::snake_case!(stringify!(#action_name_ident)).into_boxed_str()) + Box::leak(just_fmt::snake_case!(stringify!(#action_name_ident)).into_boxed_str()) } fn is_remote_action() -> bool { @@ -116,7 +116,7 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok tcp_connection::error::TcpTargetError::Serialization(e.to_string()) })?; let result_json = pool.process_json( - Box::leak(string_proc::snake_case!(stringify!(#action_name_ident)).into_boxed_str()), + Box::leak(just_fmt::snake_case!(stringify!(#action_name_ident)).into_boxed_str()), // LEAK??? OH SHIT ctx, args_json, ).await?; diff --git a/utils/string_proc/Cargo.toml b/utils/string_proc/Cargo.toml deleted file mode 100644 index 5292339..0000000 --- a/utils/string_proc/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "string_proc" -version = "0.1.0" -edition = "2024" - -[dependencies] -strip-ansi-escapes = "0.2.1" diff --git a/utils/string_proc/src/format_path.rs b/utils/string_proc/src/format_path.rs deleted file mode 100644 index d1fe849..0000000 --- a/utils/string_proc/src/format_path.rs +++ /dev/null @@ -1,187 +0,0 @@ -use std::path::{Path, PathBuf}; - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct PathFormatConfig { - pub strip_ansi: bool, - pub strip_unfriendly_chars: bool, - pub resolve_parent_dirs: bool, - pub collapse_consecutive_slashes: bool, - pub escape_backslashes: bool, -} - -impl Default for PathFormatConfig { - fn default() -> Self { - Self { - strip_ansi: true, - strip_unfriendly_chars: true, - resolve_parent_dirs: true, - collapse_consecutive_slashes: true, - escape_backslashes: true, - } - } -} - -/// Normalize an input path string into a canonical, platform‑agnostic form. -/// -/// This function removes ANSI escape sequences, unifies separators to `/`, -/// collapses duplicate slashes, strips unfriendly characters (`*`, `?`, `"`, `<`, `>`, `|`), -/// resolves simple `..` components, and preserves a trailing slash when present. -/// -/// See examples below for the exact normalization behavior. -/// -/// # Examples -/// -/// ``` -/// # use string_proc::format_path::format_path_str; -/// use std::io::Error; -/// -/// # fn main() -> Result<(), Error> { -/// assert_eq!(format_path_str("C:\\Users\\\\test")?, "C:/Users/test"); -/// assert_eq!( -/// format_path_str("/path/with/*unfriendly?chars")?, -/// "/path/with/unfriendlychars" -/// ); -/// assert_eq!(format_path_str("\x1b[31m/path\x1b[0m")?, "/path"); -/// assert_eq!(format_path_str("/home/user/dir/")?, "/home/user/dir/"); -/// assert_eq!( -/// format_path_str("/home/user/file.txt")?, -/// "/home/user/file.txt" -/// ); -/// assert_eq!( -/// format_path_str("/home/my_user/DOCS/JVCS_TEST/Workspace/../Vault/")?, -/// "/home/my_user/DOCS/JVCS_TEST/Vault/" -/// ); -/// assert_eq!(format_path_str("./home/file.txt")?, "home/file.txt"); -/// assert_eq!(format_path_str("./home/path/")?, "home/path/"); -/// assert_eq!(format_path_str("./")?, ""); -/// # Ok(()) -/// # } -/// ``` -pub fn format_path_str(path: impl Into) -> Result { - format_path_str_with_config(path, &PathFormatConfig::default()) -} - -/// Normalize an input path string into a canonical, platform‑agnostic form. -/// -/// This function removes ANSI escape sequences, unifies separators to `/`, -/// collapses duplicate slashes, strips unfriendly characters (`*`, `?`, `"`, `<`, `>`, `|`), -/// resolves simple `..` components, and preserves a trailing slash when present. -/// -/// Unlike `format_path_str`, -/// this method uses `PathFormatConfig` to precisely control -/// what should be processed -pub fn format_path_str_with_config( - path: impl Into, - config: &PathFormatConfig, -) -> Result { - let path_str = path.into(); - let ends_with_slash = path_str.ends_with('/'); - - // ANSI Strip - let cleaned = if config.strip_ansi { - strip_ansi_escapes::strip(&path_str) - } else { - path_str.as_bytes().to_vec() - }; - let path_without_ansi = String::from_utf8(cleaned) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; - - let path_with_forward_slash = if config.escape_backslashes { - path_without_ansi.replace('\\', "/") - } else { - path_without_ansi - }; - let mut result = String::new(); - let mut prev_char = '\0'; - - for c in path_with_forward_slash.chars() { - if config.collapse_consecutive_slashes && c == '/' && prev_char == '/' { - continue; - } - result.push(c); - prev_char = c; - } - - if config.strip_unfriendly_chars { - let unfriendly_chars = ['*', '?', '"', '<', '>', '|']; - result = result - .chars() - .filter(|c| !unfriendly_chars.contains(c)) - .collect(); - } - - // Handle ".." path components - let path_buf = PathBuf::from(&result); - let normalized_path = if config.resolve_parent_dirs { - normalize_path(&path_buf) - } else { - path_buf - }; - result = normalized_path.to_string_lossy().replace('\\', "/"); - - // Restore trailing slash if original path had one - if ends_with_slash && !result.ends_with('/') { - result.push('/'); - } - - // Special case: when result is only "./", return "" - if result == "./" { - return Ok(String::new()); - } - - Ok(result) -} - -/// Normalize path by resolving ".." components without requiring file system access -fn normalize_path(path: &Path) -> PathBuf { - let mut components = Vec::new(); - - for component in path.components() { - match component { - std::path::Component::ParentDir => { - if !components.is_empty() { - components.pop(); - } - } - std::path::Component::CurDir => { - // Skip current directory components - } - _ => { - components.push(component); - } - } - } - - if components.is_empty() { - PathBuf::from(".") - } else { - components.iter().collect() - } -} - -/// Format a [`PathBuf`] into its canonical string form and convert it back. -/// -/// This is a convenience wrapper around [`format_path_str`], preserving -/// the semantics of [`PathBuf`] while applying the same normalization rules: -/// - normalize separators to `/` -/// - remove duplicated separators -/// - strip ANSI escape sequences -/// - remove unfriendly characters (`*`, `?`, etc.) -/// - resolve simple `..` segments -pub fn format_path(path: impl Into) -> Result { - let path_str = format_path_str(path.into().display().to_string())?; - Ok(PathBuf::from(path_str)) -} - -/// Format a [`PathBuf`] into its canonical string form and convert it back. -/// -/// Unlike `format_path`, -/// this method uses `PathFormatConfig` to precisely control -/// what should be processed -pub fn format_path_with_config( - path: impl Into, - config: &PathFormatConfig, -) -> Result { - let path_str = format_path_str_with_config(path.into().display().to_string(), config)?; - Ok(PathBuf::from(path_str)) -} diff --git a/utils/string_proc/src/format_processer.rs b/utils/string_proc/src/format_processer.rs deleted file mode 100644 index bac84c0..0000000 --- a/utils/string_proc/src/format_processer.rs +++ /dev/null @@ -1,242 +0,0 @@ -pub struct FormatProcesser { - content: Vec, -} - -impl From for FormatProcesser { - fn from(value: String) -> Self { - Self { - content: Self::process_string(value), - } - } -} - -impl From<&str> for FormatProcesser { - fn from(value: &str) -> Self { - Self { - content: Self::process_string(value.to_string()), - } - } -} - -impl FormatProcesser { - /// Process the string into an intermediate format - fn process_string(input: String) -> Vec { - let mut result = String::new(); - let mut prev_space = false; - - for c in input.chars() { - match c { - 'a'..='z' | 'A'..='Z' | '0'..='9' => { - result.push(c); - prev_space = false; - } - '_' | ',' | '.' | '-' | ' ' => { - if !prev_space { - result.push(' '); - prev_space = true; - } - } - _ => {} - } - } - - let mut processed = String::new(); - let mut chars = result.chars().peekable(); - - while let Some(c) = chars.next() { - processed.push(c); - if let Some(&next) = chars.peek() - && c.is_lowercase() - && next.is_uppercase() - { - processed.push(' '); - } - } - - processed - .to_lowercase() - .split_whitespace() - .map(|s| s.to_string()) - .collect() - } - - /// Convert to camelCase format (brewCoffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew_coffee"); - /// assert_eq!(processor.to_camel_case(), "brewCoffee"); - /// ``` - pub fn to_camel_case(&self) -> String { - let mut result = String::new(); - for (i, word) in self.content.iter().enumerate() { - if i == 0 { - result.push_str(&word.to_lowercase()); - } else { - let mut chars = word.chars(); - if let Some(first) = chars.next() { - result.push_str(&first.to_uppercase().collect::()); - result.push_str(&chars.collect::().to_lowercase()); - } - } - } - result - } - - /// Convert to PascalCase format (BrewCoffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew_coffee"); - /// assert_eq!(processor.to_pascal_case(), "BrewCoffee"); - /// ``` - pub fn to_pascal_case(&self) -> String { - let mut result = String::new(); - for word in &self.content { - let mut chars = word.chars(); - if let Some(first) = chars.next() { - result.push_str(&first.to_uppercase().collect::()); - result.push_str(&chars.collect::().to_lowercase()); - } - } - result - } - - /// Convert to kebab-case format (brew-coffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew_coffee"); - /// assert_eq!(processor.to_kebab_case(), "brew-coffee"); - /// ``` - pub fn to_kebab_case(&self) -> String { - self.content.join("-").to_lowercase() - } - - /// Convert to snake_case format (brew_coffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brewCoffee"); - /// assert_eq!(processor.to_snake_case(), "brew_coffee"); - /// ``` - pub fn to_snake_case(&self) -> String { - self.content.join("_").to_lowercase() - } - - /// Convert to dot.case format (brew.coffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew_coffee"); - /// assert_eq!(processor.to_dot_case(), "brew.coffee"); - /// ``` - pub fn to_dot_case(&self) -> String { - self.content.join(".").to_lowercase() - } - - /// Convert to Title Case format (Brew Coffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew_coffee"); - /// assert_eq!(processor.to_title_case(), "Brew Coffee"); - /// ``` - pub fn to_title_case(&self) -> String { - let mut result = String::new(); - for word in &self.content { - let mut chars = word.chars(); - if let Some(first) = chars.next() { - result.push_str(&first.to_uppercase().collect::()); - result.push_str(&chars.collect::().to_lowercase()); - } - result.push(' '); - } - result.pop(); - result - } - - /// Convert to lower case format (brew coffee) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("BREW COFFEE"); - /// assert_eq!(processor.to_lower_case(), "brew coffee"); - /// ``` - pub fn to_lower_case(&self) -> String { - self.content.join(" ").to_lowercase() - } - - /// Convert to UPPER CASE format (BREW COFFEE) - /// - /// # Examples - /// - /// ``` - /// # use string_proc::format_processer::FormatProcesser; - /// let processor = FormatProcesser::from("brew coffee"); - /// assert_eq!(processor.to_upper_case(), "BREW COFFEE"); - /// ``` - pub fn to_upper_case(&self) -> String { - self.content.join(" ").to_uppercase() - } -} - -#[cfg(test)] -mod tests { - use crate::format_processer::FormatProcesser; - - #[test] - fn test_processer() { - let test_cases = vec![ - ("brew_coffee", "brewCoffee"), - ("brew, coffee", "brewCoffee"), - ("brew-coffee", "brewCoffee"), - ("Brew.Coffee", "brewCoffee"), - ("bRewCofFee", "bRewCofFee"), - ("brewCoffee", "brewCoffee"), - ("b&rewCoffee", "brewCoffee"), - ("BrewCoffee", "brewCoffee"), - ("brew.coffee", "brewCoffee"), - ("Brew_Coffee", "brewCoffee"), - ("BREW COFFEE", "brewCoffee"), - ]; - - for (input, expected) in test_cases { - let processor = FormatProcesser::from(input); - assert_eq!( - processor.to_camel_case(), - expected, - "Failed for input: '{}'", - input - ); - } - } - - #[test] - fn test_conversions() { - let processor = FormatProcesser::from("brewCoffee"); - - assert_eq!(processor.to_upper_case(), "BREW COFFEE"); - assert_eq!(processor.to_lower_case(), "brew coffee"); - assert_eq!(processor.to_title_case(), "Brew Coffee"); - assert_eq!(processor.to_dot_case(), "brew.coffee"); - assert_eq!(processor.to_snake_case(), "brew_coffee"); - assert_eq!(processor.to_kebab_case(), "brew-coffee"); - assert_eq!(processor.to_pascal_case(), "BrewCoffee"); - assert_eq!(processor.to_camel_case(), "brewCoffee"); - } -} diff --git a/utils/string_proc/src/lib.rs b/utils/string_proc/src/lib.rs deleted file mode 100644 index d019003..0000000 --- a/utils/string_proc/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -#[deprecated = "The module has been migrated to crates.io, please migrate to `just_fmt = \"0.1\"`"] -#[allow(deprecated)] -pub mod format_path; - -#[deprecated = "The module has been migrated to crates.io, please migrate to `just_fmt = \"0.1\"`"] -#[allow(deprecated)] -pub mod format_processer; - -#[deprecated = "The module has been migrated to crates.io, please migrate to `just_fmt = \"0.1\"`"] -#[allow(deprecated)] -pub mod macros; - -#[deprecated = "The module has been migrated to crates.io, please migrate to `just_fmt = \"0.1\"`"] -#[allow(deprecated)] -pub mod simple_processer; diff --git a/utils/string_proc/src/macros.rs b/utils/string_proc/src/macros.rs deleted file mode 100644 index 414baf0..0000000 --- a/utils/string_proc/src/macros.rs +++ /dev/null @@ -1,127 +0,0 @@ -/// Convert to camelCase format (brewCoffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::camel_case; -/// assert_eq!(camel_case!("brew_coffee"), "brewCoffee"); -/// ``` -#[macro_export] -macro_rules! camel_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_camel_case() - }}; -} - -/// Convert to UPPER CASE format (BREW COFFEE) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::upper_case; -/// assert_eq!(upper_case!("brew coffee"), "BREW COFFEE"); -/// ``` -#[macro_export] -macro_rules! upper_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_upper_case() - }}; -} - -/// Convert to lower case format (brew coffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::lower_case; -/// assert_eq!(lower_case!("BREW COFFEE"), "brew coffee"); -/// ``` -#[macro_export] -macro_rules! lower_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_lower_case() - }}; -} - -/// Convert to Title Case format (Brew Coffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::title_case; -/// assert_eq!(title_case!("brew_coffee"), "Brew Coffee"); -/// ``` -#[macro_export] -macro_rules! title_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_title_case() - }}; -} - -/// Convert to dot.case format (brew.coffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::dot_case; -/// assert_eq!(dot_case!("brew_coffee"), "brew.coffee"); -/// ``` -#[macro_export] -macro_rules! dot_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_dot_case() - }}; -} - -/// Convert to snake_case format (brew_coffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::snake_case; -/// assert_eq!(snake_case!("brewCoffee"), "brew_coffee"); -/// ``` -#[macro_export] -macro_rules! snake_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_snake_case() - }}; -} - -/// Convert to kebab-case format (brew-coffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::kebab_case; -/// assert_eq!(kebab_case!("brew_coffee"), "brew-coffee"); -/// ``` -#[macro_export] -macro_rules! kebab_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_kebab_case() - }}; -} - -/// Convert to PascalCase format (BrewCoffee) -/// -/// # Examples -/// -/// ``` -/// # use string_proc::pascal_case; -/// assert_eq!(pascal_case!("brew_coffee"), "BrewCoffee"); -/// ``` -#[macro_export] -macro_rules! pascal_case { - ($input:expr) => {{ - use string_proc::format_processer::FormatProcesser; - FormatProcesser::from($input).to_pascal_case() - }}; -} diff --git a/utils/string_proc/src/simple_processer.rs b/utils/string_proc/src/simple_processer.rs deleted file mode 100644 index 2de5dfc..0000000 --- a/utils/string_proc/src/simple_processer.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// Sanitizes a file path by replacing special characters with underscores. -/// -/// This function takes a file path as input and returns a sanitized version -/// where characters that are not allowed in file paths (such as path separators -/// and other reserved characters) are replaced with underscores. -pub fn sanitize_file_path>(path: P) -> String { - let path_str = path.as_ref(); - path_str - .chars() - .map(|c| match c { - '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_', - _ => c, - }) - .collect() -} -- cgit