Skip to main content

j_cli/command/
alias.rs

1use crate::config::YamlConfig;
2use crate::constants::section;
3use crate::constants::{MODIFY_SECTIONS, REMOVE_CLEANUP_SECTIONS, RENAME_SYNC_SECTIONS};
4use crate::{error, info, usage};
5use crate::command::all_command_keywords;
6use url::Url;
7
8/// 处理 set 命令: j set <alias> <path...>
9pub fn handle_set(alias: &str, path_parts: &[String], config: &mut YamlConfig) {
10    if path_parts.is_empty() {
11        usage!("j set <alias> <path>");
12        return;
13    }
14
15    // 检查别名是否与内置命令冲突
16    if all_command_keywords().contains(&alias) {
17        error!("别名 `{}` 已经是预设命令,请换一个。 😢", alias);
18        return;
19    }
20
21    // 处理路径中包含空格的情况:将多个参数拼接
22    let path = path_parts.join(" ");
23    let path = crate::util::remove_quotes(&path);
24    let path = path.replace("\\ ", " ");
25
26    if is_url(&path) {
27        add_as_url(alias, &path, config);
28    } else {
29        add_as_path(alias, &path, config);
30    }
31}
32
33/// 处理 remove 命令: j rm <alias>
34pub fn handle_remove(alias: &str, config: &mut YamlConfig) {
35    if config.contains(section::PATH, alias) {
36        // 如果是脚本别名,同时删除磁盘上的脚本文件
37        if let Some(script_path) = config.get_property(section::SCRIPT, alias) {
38            let path = std::path::Path::new(&script_path);
39            if path.exists() {
40                match std::fs::remove_file(path) {
41                    Ok(_) => info!("🗑️ 已删除脚本文件: {}", script_path),
42                    Err(e) => error!("⚠️ 删除脚本文件失败: {}", e),
43                }
44            }
45        }
46        config.remove_property(section::PATH, alias);
47        // 同时清理关联的 category
48        for s in REMOVE_CLEANUP_SECTIONS {
49            config.remove_property(s, alias);
50        }
51        info!("成功从 PATH 中移除别名 {} ✅", alias);
52    } else if config.contains(section::INNER_URL, alias) {
53        config.remove_property(section::INNER_URL, alias);
54        info!("成功从 INNER_URL 中移除别名 {} ✅", alias);
55    } else if config.contains(section::OUTER_URL, alias) {
56        config.remove_property(section::OUTER_URL, alias);
57        info!("成功从 OUTER_URL 中移除别名 {} ✅", alias);
58    } else {
59        error!("别名 {} 不存在 ❌", alias);
60    }
61}
62
63/// 处理 rename 命令: j rename <alias> <new_alias>
64pub fn handle_rename(alias: &str, new_alias: &str, config: &mut YamlConfig) {
65    let mut updated = false;
66
67    // path
68    if config.contains(section::PATH, alias) {
69        let path = config.get_property(section::PATH, alias).cloned().unwrap_or_default();
70        config.rename_property(section::PATH, alias, new_alias);
71        // 同时重命名关联的 category
72        for s in RENAME_SYNC_SECTIONS {
73            config.rename_property(s, alias, new_alias);
74        }
75        updated = true;
76        info!("✅ 重命名 {} -> {} 成功! Path: {} 🎉", alias, new_alias, path);
77    }
78
79    // inner_url
80    if config.contains(section::INNER_URL, alias) {
81        let url = config.get_property(section::INNER_URL, alias).cloned().unwrap_or_default();
82        config.rename_property(section::INNER_URL, alias, new_alias);
83        updated = true;
84        info!("✅ 重命名 {} -> {} 成功! Inner URL: {} 🚀", alias, new_alias, url);
85    }
86
87    // outer_url
88    if config.contains(section::OUTER_URL, alias) {
89        let url = config.get_property(section::OUTER_URL, alias).cloned().unwrap_or_default();
90        config.rename_property(section::OUTER_URL, alias, new_alias);
91        updated = true;
92        info!("✅ 重命名 {} -> {} 成功! Outer URL: {} 🌐", alias, new_alias, url);
93    }
94
95    if !updated {
96        error!("❌ 别名 {} 不存在!", alias);
97    }
98}
99
100/// 处理 modify 命令: j mf <alias> <new_path...>
101pub fn handle_modify(alias: &str, path_parts: &[String], config: &mut YamlConfig) {
102    if path_parts.is_empty() {
103        usage!("j mf <alias> <new_path>");
104        return;
105    }
106
107    let path = path_parts.join(" ");
108    let path = crate::util::remove_quotes(&path);
109    let path = path.replace("\\ ", " ");
110
111    let mut has_modified = false;
112
113    // 依次检查各个 section 并更新
114    for s in MODIFY_SECTIONS {
115        if config.contains(s, alias) {
116            config.set_property(s, alias, &path);
117            has_modified = true;
118            info!("修改 {} 在 {} 下的值为 {{{}}} 成功 ✅", alias, s, path);
119        }
120    }
121
122    if !has_modified {
123        error!("别名 {} 不存在,请先使用 set 命令添加。", alias);
124    }
125}
126
127// ========== 辅助函数 ==========
128
129/// 判断是否为 URL
130fn is_url(input: &str) -> bool {
131    if input.is_empty() {
132        return false;
133    }
134    Url::parse(input)
135        .map(|u| u.scheme() == "http" || u.scheme() == "https")
136        .unwrap_or(false)
137}
138
139/// 添加为路径别名
140fn add_as_path(alias: &str, path: &str, config: &mut YamlConfig) {
141    if config.contains(section::PATH, alias) {
142        error!(
143            "别名 {} 的路径 {{{}}} 已存在。 😢 请使用 `mf` 命令修改",
144            alias,
145            config.get_property(section::PATH, alias).unwrap()
146        );
147    } else {
148        config.set_property(section::PATH, alias, path);
149        info!("✅ 添加别名 {} -> {{{}}} 成功! 🎉", alias, path);
150    }
151}
152
153/// 添加为 URL 别名
154fn add_as_url(alias: &str, url: &str, config: &mut YamlConfig) {
155    if config.contains(section::INNER_URL, alias) || config.contains(section::OUTER_URL, alias) {
156        error!("别名 {} 已存在。 😢 请使用 `mf` 命令修改", alias);
157    } else {
158        config.set_property(section::INNER_URL, alias, url);
159        info!("✅ 添加别名 {} -> {{{}}} 成功! 🚀", alias, url);
160    }
161}