Skip to content

Commit d955ac1

Browse files
committed
格式化代码提高可读性
1 parent 5029439 commit d955ac1

File tree

5 files changed

+122
-75
lines changed

5 files changed

+122
-75
lines changed

src/api.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// src/api.rs
22

3-
use anyhow::{anyhow, Context, Result};
3+
use anyhow::{Context, Result, anyhow};
44
use reqwest::blocking::Client;
55
use serde::Deserialize;
66
use std::collections::HashMap;
@@ -59,10 +59,7 @@ impl ApiClient {
5959
if response.status().is_success() {
6060
return Ok(response);
6161
} else {
62-
last_error = Some(anyhow!(
63-
"API 请求失败,状态码: {}",
64-
response.status()
65-
));
62+
last_error = Some(anyhow!("API 请求失败,状态码: {}", response.status()));
6663
}
6764
}
6865
Err(e) => {
@@ -80,10 +77,8 @@ impl ApiClient {
8077

8178
pub fn list_voices(&self) -> Result<Vec<Voice>> {
8279
let url = format!("{}/voices", self.base_url);
83-
84-
let response = self.send_request_with_retry(|| {
85-
self.client.get(&url).build()
86-
})?;
80+
81+
let response = self.send_request_with_retry(|| self.client.get(&url).build())?;
8782

8883
let parsed_response = response
8984
.json::<VoicesResponse>()
@@ -113,17 +108,23 @@ impl ApiClient {
113108
) -> Result<Vec<u8>> {
114109
let mut url = url::Url::parse(&format!("{}/forward", self.base_url))
115110
.context("无法解析 /forward API 地址")?;
116-
111+
117112
url.query_pairs_mut().append_pair("text", text);
118-
if let Some(v) = voice { url.query_pairs_mut().append_pair("voice", v); }
119-
if let Some(v) = volume { url.query_pairs_mut().append_pair("volume", &v.to_string()); }
120-
if let Some(v) = speed { url.query_pairs_mut().append_pair("speed", &v.to_string()); }
121-
if let Some(v) = pitch { url.query_pairs_mut().append_pair("pitch", &v.to_string()); }
113+
if let Some(v) = voice {
114+
url.query_pairs_mut().append_pair("voice", v);
115+
}
116+
if let Some(v) = volume {
117+
url.query_pairs_mut().append_pair("volume", &v.to_string());
118+
}
119+
if let Some(v) = speed {
120+
url.query_pairs_mut().append_pair("speed", &v.to_string());
121+
}
122+
if let Some(v) = pitch {
123+
url.query_pairs_mut().append_pair("pitch", &v.to_string());
124+
}
122125

123126
let request_url = url.to_string();
124-
let response = self.send_request_with_retry(|| {
125-
self.client.get(&request_url).build()
126-
})?;
127+
let response = self.send_request_with_retry(|| self.client.get(&request_url).build())?;
127128

128129
let bytes = response.bytes().context("读取音频响应体失败")?.to_vec();
129130
Ok(bytes)

src/lrc.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ pub fn generate_lrc(
1515
let mut lrc_content = String::new();
1616

1717
// 歌词文件最上方添加 LRC 元数据标签
18-
let file_name = output_path.file_stem().unwrap_or_default().to_string_lossy();
18+
let file_name = output_path
19+
.file_stem()
20+
.unwrap_or_default()
21+
.to_string_lossy();
1922
lrc_content.push_str("[ar:Generated by BaiTTS CLI-rs]\n");
2023
lrc_content.push_str("[al:Audio]\n");
2124
lrc_content.push_str(&format!("[ti:{}]\n\n", file_name));
@@ -53,7 +56,7 @@ pub fn generate_lrc(
5356
// 为每个小行生成带时间戳的歌词
5457
for (j, chunk) in chunks.iter().enumerate() {
5558
let chunk_start_time = line_start_time + chunk_duration * j as u32;
56-
59+
5760
let minutes = chunk_start_time.as_secs() / 60;
5861
let seconds = chunk_start_time.as_secs() % 60;
5962
let millis = chunk_start_time.subsec_millis() / 10;
@@ -64,16 +67,16 @@ pub fn generate_lrc(
6467
}
6568

6669
let lrc_path = PathBuf::from(output_path).with_extension("lrc");
67-
fs::write(&lrc_path, lrc_content)
68-
.context(format!("无法写入 LRC 文件到 {:?}", lrc_path))?;
69-
70+
fs::write(&lrc_path, lrc_content).context(format!("无法写入 LRC 文件到 {:?}", lrc_path))?;
71+
7072
println!("成功生成 LRC 文件: {:?}", lrc_path);
7173
Ok(())
7274
}
7375

7476
// 查找理想的分割点(各类标点符号或空格)。
7577
fn is_break_character(c: char) -> bool {
76-
matches!(c,
78+
matches!(
79+
c,
7780
// 中文常用标点 (全角)
7881
',' | '。' | '?' | '!' | ';' | ':' | '、' |
7982
// 英文常用标点 (半角)
@@ -98,7 +101,9 @@ fn split_line_intelligently(line: &str, max_chars: usize) -> Vec<String> {
98101
let mut current_pos = 0;
99102

100103
// 循环前,先跳过所有行首的无效字符
101-
while current_pos < chars.len() && (chars[current_pos].is_whitespace() || is_break_character(chars[current_pos])) {
104+
while current_pos < chars.len()
105+
&& (chars[current_pos].is_whitespace() || is_break_character(chars[current_pos]))
106+
{
102107
current_pos += 1;
103108
}
104109

@@ -107,47 +112,66 @@ fn split_line_intelligently(line: &str, max_chars: usize) -> Vec<String> {
107112
let chunk = chars[current_pos..].iter().collect::<String>();
108113
let trimmed_chunk = chunk.trim();
109114
if !trimmed_chunk.is_empty() {
110-
chunks.push(trimmed_chunk.to_string());
115+
chunks.push(trimmed_chunk.to_string());
111116
}
112117
break;
113118
}
114119

115120
let search_end = current_pos + max_chars;
116121
let search_range = &chars[current_pos..search_end];
117122

118-
if let Some(split_pos_relative) = search_range.iter().rposition(|&c| is_break_character(c)) {
123+
if let Some(split_pos_relative) = search_range.iter().rposition(|&c| is_break_character(c))
124+
{
119125
// 找到了理想的分割点(在max_chars范围内)
120126
let split_pos_absolute = current_pos + split_pos_relative;
121-
let chunk = chars[current_pos..=split_pos_absolute].iter().collect::<String>().trim().to_string();
127+
let chunk = chars[current_pos..=split_pos_absolute]
128+
.iter()
129+
.collect::<String>()
130+
.trim()
131+
.to_string();
122132
if !chunk.is_empty() {
123133
chunks.push(chunk);
124134
}
125-
135+
126136
let mut next_pos = split_pos_absolute + 1;
127-
while next_pos < chars.len() && (chars[next_pos].is_whitespace() || is_break_character(chars[next_pos])) {
137+
while next_pos < chars.len()
138+
&& (chars[next_pos].is_whitespace() || is_break_character(chars[next_pos]))
139+
{
128140
next_pos += 1;
129141
}
130142
current_pos = next_pos;
131-
132143
} else {
133144
// 在max_chars范围内未找到分割点,因此向前查找下一个分割点
134145
// 从 search_end 开始向字符串末尾搜索
135-
if let Some(next_break_relative) = chars[search_end..].iter().position(|&c| is_break_character(c)) {
146+
if let Some(next_break_relative) = chars[search_end..]
147+
.iter()
148+
.position(|&c| is_break_character(c))
149+
{
136150
// 找到了下一个分割点
137151
let split_pos_absolute = search_end + next_break_relative;
138-
let chunk = chars[current_pos..=split_pos_absolute].iter().collect::<String>().trim().to_string();
152+
let chunk = chars[current_pos..=split_pos_absolute]
153+
.iter()
154+
.collect::<String>()
155+
.trim()
156+
.to_string();
139157
if !chunk.is_empty() {
140158
chunks.push(chunk);
141159
}
142160

143161
let mut next_pos = split_pos_absolute + 1;
144-
while next_pos < chars.len() && (chars[next_pos].is_whitespace() || is_break_character(chars[next_pos])) {
162+
while next_pos < chars.len()
163+
&& (chars[next_pos].is_whitespace() || is_break_character(chars[next_pos]))
164+
{
145165
next_pos += 1;
146166
}
147167
current_pos = next_pos;
148168
} else {
149169
// 从 search_end 到字符串末尾都没有任何分割点,将剩余部分全部作为一块
150-
let chunk = chars[current_pos..].iter().collect::<String>().trim().to_string();
170+
let chunk = chars[current_pos..]
171+
.iter()
172+
.collect::<String>()
173+
.trim()
174+
.to_string();
151175
if !chunk.is_empty() {
152176
chunks.push(chunk);
153177
}

src/main.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod lrc;
66
mod process;
77
mod utils;
88

9-
use anyhow::{anyhow, Result};
9+
use anyhow::{Result, anyhow};
1010
use clap::Parser;
1111
use std::io;
1212
use std::path::Path;
@@ -20,7 +20,7 @@ fn main() -> Result<()> {
2020
let api_url = args.api.as_ref().unwrap();
2121
let client = api::ApiClient::new(api_url.clone())?;
2222
let voices = client.list_voices()?;
23-
23+
2424
println!("可用的声音列表:");
2525
for voice in voices {
2626
println!("{}", "=".repeat(50));
@@ -31,7 +31,6 @@ fn main() -> Result<()> {
3131
println!("类型: {}", voice.voice_type);
3232
}
3333
println!("{}", "=".repeat(50));
34-
3534
} else if let Some(file_path) = &args.file {
3635
// --- 单文件处理逻辑也采用新的预扫描流程 ---
3736
let api_url = args.api.as_ref().unwrap();
@@ -47,9 +46,13 @@ fn main() -> Result<()> {
4746

4847
if let Some(info) = files_to_convert.first() {
4948
println!("警告:文件 {:?} 的编码可能不是 UTF-8。", info.path);
50-
println!("检测为: {} (置信度: {:.1}%)", info.encoding, info.confidence * 100.0);
49+
println!(
50+
"检测为: {} (置信度: {:.1}%)",
51+
info.encoding,
52+
info.confidence * 100.0
53+
);
5154
println!("是否要将其转换为 UTF-8 编码?(此操作将覆盖原文件) (y/N)");
52-
55+
5356
let mut input = String::new();
5457
io::stdin().read_line(&mut input)?;
5558
if input.trim().to_lowercase() == "y" {
@@ -58,9 +61,8 @@ fn main() -> Result<()> {
5861
return Err(anyhow!("用户取消了编码转换,终止操作。"));
5962
}
6063
}
61-
62-
process::process_file(file_path, &args, &client, &blacklist)?;
6364

65+
process::process_file(file_path, &args, &client, &blacklist)?;
6466
} else if let Some(dir_path) = &args.dir {
6567
let api_url = args.api.as_ref().unwrap();
6668
let client = api::ApiClient::new(api_url.clone())?;
@@ -69,7 +71,6 @@ fn main() -> Result<()> {
6971
None => None,
7072
};
7173
process::process_directory(dir_path, &args, &client, &blacklist)?;
72-
7374
} else {
7475
println!("错误:没有指定操作 (使用 -h 或 --help 获取帮助)");
7576
}
@@ -81,7 +82,14 @@ fn validate_args(args: &args::Cli) -> Result<()> {
8182
let has_file_op = args.file.is_some() || args.dir.is_some();
8283

8384
if args.list {
84-
if has_file_op || args.voice.is_some() || args.volume.is_some() || args.speed.is_some() || args.pitch.is_some() || args.sub.is_some() || args.blacklist.is_some() {
85+
if has_file_op
86+
|| args.voice.is_some()
87+
|| args.volume.is_some()
88+
|| args.speed.is_some()
89+
|| args.pitch.is_some()
90+
|| args.sub.is_some()
91+
|| args.blacklist.is_some()
92+
{
8593
return Err(anyhow!("使用 --list 时,只允许提供 --api 参数。"));
8694
}
8795
if args.api.is_none() {
@@ -92,12 +100,16 @@ fn validate_args(args: &args::Cli) -> Result<()> {
92100
return Err(anyhow!("使用 --file 或 --dir 时,必须提供 --api 参数。"));
93101
}
94102
if let Some(file) = &args.file {
95-
if !Path::new(file).exists() { return Err(anyhow!("文件不存在: {:?}", file)); }
103+
if !Path::new(file).exists() {
104+
return Err(anyhow!("文件不存在: {:?}", file));
105+
}
96106
}
97-
if let Some(file) = &args.file && !Path::new(file).exists() {
98-
return Err(anyhow!("文件不存在: {:?}", file));
107+
if let Some(file) = &args.file
108+
&& !Path::new(file).exists()
109+
{
110+
return Err(anyhow!("文件不存在: {:?}", file));
99111
}
100112
}
101-
113+
102114
Ok(())
103115
}

src/process.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::api::ApiClient;
44
use crate::args::Cli;
55
use crate::lrc;
66
use crate::utils;
7-
use anyhow::{anyhow, Context, Result};
7+
use anyhow::{Context, Result, anyhow};
88
use hound::{WavReader, WavWriter};
99
use indicatif::{ProgressBar, ProgressStyle};
1010
use regex::Regex;
@@ -22,8 +22,8 @@ pub fn process_file(
2222
) -> Result<()> {
2323
println!("正在处理文件: {:?}", file_path);
2424

25-
let content = fs::read_to_string(file_path)
26-
.context(format!("无法读取文件内容: {:?}", file_path))?;
25+
let content =
26+
fs::read_to_string(file_path).context(format!("无法读取文件内容: {:?}", file_path))?;
2727
let mut lines: Vec<String> = content.lines().map(String::from).collect();
2828

2929
if lines.is_empty() {
@@ -42,9 +42,13 @@ pub fn process_file(
4242
let mut original_lines_for_lrc = Vec::new();
4343

4444
let pb = ProgressBar::new(lines.len() as u64);
45-
pb.set_style(ProgressStyle::default_bar()
46-
.template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})")?
47-
.progress_chars("#>-"));
45+
pb.set_style(
46+
ProgressStyle::default_bar()
47+
.template(
48+
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})",
49+
)?
50+
.progress_chars("#>-"),
51+
);
4852

4953
for (i, line) in lines.iter().enumerate() {
5054
if line.trim().is_empty() {
@@ -72,7 +76,7 @@ pub fn process_file(
7276
let reader = WavReader::new(BufReader::new(File::open(&chunk_path)?))?;
7377
let duration_ms = (reader.len() as f64 / reader.spec().sample_rate as f64) * 1000.0;
7478
durations.push(Duration::from_millis(duration_ms as u64));
75-
79+
7680
audio_chunks.push(chunk_path);
7781
if args.sub.is_some() {
7882
original_lines_for_lrc.push(line.clone());
@@ -83,14 +87,19 @@ pub fn process_file(
8387

8488
let output_filename = file_path.file_stem().unwrap().to_str().unwrap();
8589
let output_path = args.out.join(format!("{}.wav", output_filename));
86-
90+
8791
fs::create_dir_all(&args.out).context("创建输出目录失败")?;
88-
92+
8993
combine_wav_files(&audio_chunks, &output_path)?;
9094
println!("成功合成音频文件: {:?}", output_path);
9195

9296
if let Some(chars_per_line) = args.sub {
93-
lrc::generate_lrc(&output_path, &original_lines_for_lrc, &durations, chars_per_line)?;
97+
lrc::generate_lrc(
98+
&output_path,
99+
&original_lines_for_lrc,
100+
&durations,
101+
chars_per_line,
102+
)?;
94103
}
95104

96105
Ok(())
@@ -107,7 +116,7 @@ pub fn process_directory(
107116
.map(|e| e.path())
108117
.filter(|p| p.is_file() && p.extension().is_some_and(|ext| ext == "txt"))
109118
.collect();
110-
119+
111120
entries.sort();
112121

113122
if entries.is_empty() {
@@ -152,7 +161,7 @@ pub fn process_directory(
152161
process_file(&entry, args, client, blacklist)?;
153162
println!("--------------------------------------------------");
154163
}
155-
164+
156165
println!("所有文件处理完毕。");
157166
Ok(())
158167
}
@@ -170,7 +179,10 @@ fn combine_wav_files(files: &[PathBuf], output_path: &Path) -> Result<()> {
170179
for file in files {
171180
let mut reader = WavReader::open(file)?;
172181
if reader.spec() != spec {
173-
eprintln!("警告: 文件 {:?} 的 WAV 格式与第一个文件不同,跳过合并。", file);
182+
eprintln!(
183+
"警告: 文件 {:?} 的 WAV 格式与第一个文件不同,跳过合并。",
184+
file
185+
);
174186
continue;
175187
}
176188
let samples = reader.samples::<i16>().collect::<Result<Vec<_>, _>>()?;

0 commit comments

Comments
 (0)