Skip to main content

j_cli/command/
alias.rs

1use crate::command::all_command_keywords;
2use crate::config::YamlConfig;
3use crate::constants::section;
4use crate::constants::{MODIFY_SECTIONS, REMOVE_CLEANUP_SECTIONS, RENAME_SYNC_SECTIONS};
5use crate::{error, info, usage};
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
70            .get_property(section::PATH, alias)
71            .cloned()
72            .unwrap_or_default();
73        config.rename_property(section::PATH, alias, new_alias);
74        // 同时重命名关联的 category
75        for s in RENAME_SYNC_SECTIONS {
76            config.rename_property(s, alias, new_alias);
77        }
78        updated = true;
79        info!(
80            "✅ 重命名 {} -> {} 成功! Path: {} 🎉",
81            alias, new_alias, path
82        );
83    }
84
85    // inner_url
86    if config.contains(section::INNER_URL, alias) {
87        let url = config
88            .get_property(section::INNER_URL, alias)
89            .cloned()
90            .unwrap_or_default();
91        config.rename_property(section::INNER_URL, alias, new_alias);
92        updated = true;
93        info!(
94            "✅ 重命名 {} -> {} 成功! Inner URL: {} 🚀",
95            alias, new_alias, url
96        );
97    }
98
99    // outer_url
100    if config.contains(section::OUTER_URL, alias) {
101        let url = config
102            .get_property(section::OUTER_URL, alias)
103            .cloned()
104            .unwrap_or_default();
105        config.rename_property(section::OUTER_URL, alias, new_alias);
106        updated = true;
107        info!(
108            "✅ 重命名 {} -> {} 成功! Outer URL: {} 🌐",
109            alias, new_alias, url
110        );
111    }
112
113    if !updated {
114        error!("❌ 别名 {} 不存在!", alias);
115    }
116}
117
118/// 处理 modify 命令: j mf <alias> <new_path...>
119pub fn handle_modify(alias: &str, path_parts: &[String], config: &mut YamlConfig) {
120    if path_parts.is_empty() {
121        usage!("j mf <alias> <new_path>");
122        return;
123    }
124
125    let path = path_parts.join(" ");
126    let path = crate::util::remove_quotes(&path);
127    let path = path.replace("\\ ", " ");
128
129    let mut has_modified = false;
130
131    // 依次检查各个 section 并更新
132    for s in MODIFY_SECTIONS {
133        if config.contains(s, alias) {
134            config.set_property(s, alias, &path);
135            has_modified = true;
136            info!("修改 {} 在 {} 下的值为 {{{}}} 成功 ✅", alias, s, path);
137        }
138    }
139
140    if !has_modified {
141        error!("别名 {} 不存在,请先使用 set 命令添加。", alias);
142    }
143}
144
145// ========== 辅助函数 ==========
146
147/// 判断是否为 URL
148fn is_url(input: &str) -> bool {
149    if input.is_empty() {
150        return false;
151    }
152    Url::parse(input)
153        .map(|u| u.scheme() == "http" || u.scheme() == "https")
154        .unwrap_or(false)
155}
156
157/// 添加为路径别名
158fn add_as_path(alias: &str, path: &str, config: &mut YamlConfig) {
159    if config.contains(section::PATH, alias) {
160        error!(
161            "别名 {} 的路径 {{{}}} 已存在。 😢 请使用 `mf` 命令修改",
162            alias,
163            config.get_property(section::PATH, alias).unwrap()
164        );
165    } else {
166        config.set_property(section::PATH, alias, path);
167        info!("✅ 添加别名 {} -> {{{}}} 成功! 🎉", alias, path);
168    }
169}
170
171/// 添加为 URL 别名
172fn add_as_url(alias: &str, url: &str, config: &mut YamlConfig) {
173    if config.contains(section::INNER_URL, alias) || config.contains(section::OUTER_URL, alias) {
174        error!("别名 {} 已存在。 😢 请使用 `mf` 命令修改", alias);
175    } else {
176        config.set_property(section::INNER_URL, alias, url);
177        info!("✅ 添加别名 {} -> {{{}}} 成功! 🚀", alias, url);
178    }
179}