summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock32
-rw-r--r--Cargo.toml4
-rw-r--r--legacy_actions/Cargo.toml3
-rw-r--r--legacy_data/Cargo.toml4
-rw-r--r--legacy_data/src/data/local.rs7
-rw-r--r--legacy_data/src/data/local/cached_sheet.rs12
-rw-r--r--legacy_data/src/data/local/local_files.rs4
-rw-r--r--legacy_data/src/data/local/local_sheet.rs27
-rw-r--r--legacy_data/src/data/local/workspace_analyzer.rs4
-rw-r--r--legacy_data/src/data/local/workspace_config.rs2
-rw-r--r--legacy_data/src/data/member.rs2
-rw-r--r--legacy_data/src/data/vault/mapping_share.rs4
-rw-r--r--legacy_data/src/data/vault/sheet_manage.rs2
-rw-r--r--legacy_data/src/data/vault/virtual_file.rs2
-rw-r--r--src/lib.rs7
-rw-r--r--systems/action/action_macros/Cargo.toml3
-rw-r--r--systems/action/action_macros/src/lib.rs4
-rw-r--r--utils/string_proc/Cargo.toml7
-rw-r--r--utils/string_proc/src/format_path.rs187
-rw-r--r--utils/string_proc/src/format_processer.rs242
-rw-r--r--utils/string_proc/src/lib.rs15
-rw-r--r--utils/string_proc/src/macros.rs127
-rw-r--r--utils/string_proc/src/simple_processer.rs15
23 files changed, 55 insertions, 661 deletions
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",
@@ -1567,22 +1566,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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",
@@ -1838,15 +1821,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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<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()))?;
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<String>) -> Result<String, std::io::Error> {
- 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<String>,
- config: &PathFormatConfig,
-) -> Result<String, std::io::Error> {
- 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<PathBuf>) -> Result<PathBuf, std::io::Error> {
- 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<PathBuf>,
- config: &PathFormatConfig,
-) -> Result<PathBuf, std::io::Error> {
- 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<String>,
-}
-
-impl From<String> 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<String> {
- 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::<String>());
- result.push_str(&chars.collect::<String>().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::<String>());
- result.push_str(&chars.collect::<String>().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::<String>());
- result.push_str(&chars.collect::<String>().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<P: AsRef<str>>(path: P) -> String {
- let path_str = path.as_ref();
- path_str
- .chars()
- .map(|c| match c {
- '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_',
- _ => c,
- })
- .collect()
-}