use clap::Parser;
use std::process;
use yufmath::cli::args::{CliArgs, Commands, OutputFormat};
use yufmath::cli::interactive;
use yufmath::cli::progress::{create_compute_progress, create_batch_progress};
use yufmath::cli::terminal::init_terminal;
use yufmath::formatter::{FormatOptions, FormatType};
use yufmath::Yufmath;
fn main() {
if let Err(e) = init_terminal() {
eprintln!("警告: 终端初始化失败: {}", e);
eprintln!("颜色输出可能无法正常工作");
}
let args = CliArgs::parse();
if args.verbose {
println!("Yufmath v{} - 计算机代数系统", yufmath::VERSION);
println!("详细模式已启用");
}
let mut yuf = match create_yufmath_instance(&args) {
Ok(instance) => instance,
Err(e) => {
eprintln!("错误:无法初始化 Yufmath: {}", e);
process::exit(1);
}
};
let format_options = FormatOptions {
format_type: match args.format {
OutputFormat::Standard => FormatType::Standard,
OutputFormat::Latex => FormatType::LaTeX,
OutputFormat::Mathml => FormatType::MathML,
},
precision: args.precision,
use_parentheses: true,
};
yuf.set_format_options(format_options);
let result = match &args.command {
Some(Commands::Compute { expression }) => {
handle_compute(&yuf, expression, &args)
}
Some(Commands::Simplify { expression }) => {
handle_simplify(&yuf, expression, &args)
}
Some(Commands::Diff { expression, variable }) => {
handle_diff(&yuf, expression, variable, &args)
}
Some(Commands::Integrate { expression, variable }) => {
handle_integrate(&yuf, expression, variable, &args)
}
Some(Commands::Solve { equation, variable }) => {
handle_solve(&yuf, equation, variable, &args)
}
Some(Commands::Factor { expression }) => {
handle_factor(&yuf, expression, &args)
}
Some(Commands::Expand { expression }) => {
handle_expand(&yuf, expression, &args)
}
Some(Commands::Limit { expression, variable, point }) => {
handle_limit(&yuf, expression, variable, point, &args)
}
Some(Commands::Series { expression, variable, point, order }) => {
handle_series(&yuf, expression, variable, point, *order, &args)
}
Some(Commands::Batch { input, output }) => {
handle_batch(&yuf, input, output.as_deref(), &args)
}
Some(Commands::Interactive) => {
handle_interactive(&args)
}
Some(Commands::Notepad { file, title, terminal }) => {
if let Err(e) = yufmath::cli::run_command(args) {
eprintln!("错误: {}", e);
process::exit(1);
}
return;
}
None => {
handle_interactive(&args)
}
};
match result {
Ok(()) => {
if args.verbose {
println!("计算完成");
}
}
Err(e) => {
if !args.quiet {
eprintln!("错误: {}", e);
}
process::exit(1);
}
}
}
fn create_yufmath_instance(_args: &CliArgs) -> Result<Yufmath, Box<dyn std::error::Error>> {
Ok(Yufmath::new())
}
fn handle_compute(yuf: &Yufmath, expression: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
let show_progress = args.progress && !args.no_progress && !args.quiet;
let progress = create_compute_progress(show_progress, "计算表达式");
if args.verbose {
println!("正在计算表达式: {}", expression);
}
let result = yuf.compute(expression)?;
progress.finish("计算完成");
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_simplify(yuf: &Yufmath, expression: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在简化表达式: {}", expression);
}
let expr = yuf.parse(expression)?;
let simplified = yuf.simplify(&expr)?;
use yufmath::formatter::{StandardFormatter, Formatter};
let formatter = StandardFormatter::new();
let result = formatter.format(&simplified);
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_diff(yuf: &Yufmath, expression: &str, variable: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在对表达式 {} 关于变量 {} 求导", expression, variable);
}
let expr = yuf.parse(expression)?;
let derivative = yuf.diff(&expr, variable)?;
use yufmath::formatter::{StandardFormatter, Formatter};
let formatter = StandardFormatter::new();
let result = formatter.format(&derivative);
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_integrate(yuf: &Yufmath, expression: &str, variable: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在对表达式 {} 关于变量 {} 积分", expression, variable);
}
let expr = yuf.parse(expression)?;
let integral = yuf.integrate(&expr, variable)?;
use yufmath::formatter::{StandardFormatter, Formatter};
let formatter = StandardFormatter::new();
let result = formatter.format(&integral);
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_solve(yuf: &Yufmath, equation: &str, variable: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在求解方程 {} 关于变量 {}", equation, variable);
}
if !args.quiet {
println!("求解功能暂未实现,方程: {}, 变量: {}", equation, variable);
}
Ok(())
}
fn handle_factor(yuf: &Yufmath, expression: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在对表达式 {} 进行因式分解", expression);
}
if !args.quiet {
println!("因式分解功能暂未实现,表达式: {}", expression);
}
Ok(())
}
fn handle_expand(yuf: &Yufmath, expression: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在展开表达式 {}", expression);
}
if !args.quiet {
println!("展开功能暂未实现,表达式: {}", expression);
}
Ok(())
}
fn handle_limit(yuf: &Yufmath, expression: &str, variable: &str, point: &str, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在计算表达式 {} 当 {} 趋向 {} 时的极限", expression, variable, point);
}
let expr = yuf.parse(expression)?;
let point_expr = yuf.parse(point)?;
let limit_result = yuf.limit(&expr, variable, &point_expr)?;
use yufmath::formatter::{StandardFormatter, Formatter};
let formatter = StandardFormatter::new();
let result = formatter.format(&limit_result);
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_series(yuf: &Yufmath, expression: &str, variable: &str, point: &str, order: usize, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("正在对表达式 {} 在 {} = {} 处进行 {} 阶级数展开", expression, variable, point, order);
}
let expr = yuf.parse(expression)?;
let point_expr = yuf.parse(point)?;
let series_result = yuf.series(&expr, variable, &point_expr, order)?;
use yufmath::formatter::{StandardFormatter, Formatter};
let formatter = StandardFormatter::new();
let result = formatter.format(&series_result);
if !args.quiet {
println!("{}", result);
}
Ok(())
}
fn handle_batch(yuf: &Yufmath, input_file: &str, output_file: Option<&str>, args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
use std::fs;
use std::io::Write;
if args.verbose {
println!("正在处理批处理文件: {}", input_file);
if let Some(output) = output_file {
println!("输出文件: {}", output);
}
}
let content = fs::read_to_string(input_file)
.map_err(|e| format!("无法读取输入文件 '{}': {}", input_file, e))?;
let total_lines = content.lines()
.filter(|line| {
let line = line.trim();
!line.is_empty() && !line.starts_with('#') && !line.starts_with("//")
})
.count() as u64;
let show_progress = args.progress && !args.no_progress && !args.quiet;
let progress = create_batch_progress(show_progress, total_lines);
let mut results = Vec::new();
let mut line_number = 0;
let mut processed_lines = 0;
for line in content.lines() {
line_number += 1;
let line = line.trim();
if line.is_empty() || line.starts_with('#') || line.starts_with("//") {
continue;
}
processed_lines += 1;
progress.update(processed_lines, Some(&format!("处理第 {} 行", line_number)));
if args.verbose {
println!("处理第 {} 行: {}", line_number, line);
}
match yuf.compute(line) {
Ok(result) => {
let output_line = format!("{} = {}", line, result);
results.push(output_line.clone());
if !args.quiet && !show_progress {
println!("{}", output_line);
}
}
Err(e) => {
let error_line = format!("第 {} 行错误: {} -> {}", line_number, line, e);
results.push(error_line.clone());
if !args.quiet && !show_progress {
eprintln!("{}", error_line);
}
}
}
}
progress.finish(&format!("批处理完成,处理了 {} 行", processed_lines));
if show_progress && !args.quiet {
for result in &results {
if result.contains("错误") {
eprintln!("{}", result);
} else {
println!("{}", result);
}
}
}
if let Some(output_path) = output_file {
let mut output = fs::File::create(output_path)
.map_err(|e| format!("无法创建输出文件 '{}': {}", output_path, e))?;
for result in &results {
writeln!(output, "{}", result)
.map_err(|e| format!("写入输出文件失败: {}", e))?;
}
if args.verbose {
println!("结果已写入文件: {}", output_path);
}
}
Ok(())
}
fn show_help() {
println!("Yufmath v{} - 计算机代数系统", yufmath::VERSION);
println!();
println!("用法:");
println!(" yufmath [选项] <命令> [参数...]");
println!();
println!("命令:");
println!(" compute <表达式> 计算表达式的值");
println!(" simplify <表达式> 简化表达式");
println!(" diff <表达式> <变量> 对表达式求导");
println!(" integrate <表达式> <变量> 对表达式积分");
println!(" solve <方程> <变量> 求解方程");
println!(" factor <表达式> 因式分解");
println!(" expand <表达式> 展开表达式");
println!(" limit <表达式> <变量> <点> 计算极限");
println!(" series <表达式> <变量> <点> 级数展开");
println!(" batch -i <文件> [-o <文件>] 批处理模式");
println!(" interactive 交互模式");
println!(" notepad [文件] [-t <标题>] 笔记本模式");
println!();
println!("选项:");
println!(" -f, --format <格式> 输出格式 [standard, latex, mathml]");
println!(" -p, --precision <精度> 数值精度");
println!(" -v, --verbose 详细输出");
println!(" -q, --quiet 静默模式");
println!(" --progress 显示进度条");
println!(" --no-progress 禁用进度条");
println!(" --timeout <秒> 计算超时时间");
println!(" -h, --help 显示帮助信息");
println!(" --version 显示版本信息");
println!();
println!("示例:");
println!(" yufmath compute \"2 + 3 * 4\"");
println!(" yufmath simplify \"x^2 + 2*x + 1\"");
println!(" yufmath diff \"x^3 + 2*x^2 + x\" x");
println!(" yufmath integrate \"2*x + 1\" x");
println!(" yufmath --format latex compute \"x^2 + 1\"");
println!(" yufmath batch -i input.txt -o output.txt");
println!(" yufmath interactive");
println!(" yufmath notepad");
println!(" yufmath notepad my_notebook.ynb");
println!(" yufmath notepad -t \"我的数学笔记\"");
}
fn handle_interactive(args: &CliArgs) -> Result<(), Box<dyn std::error::Error>> {
if args.verbose {
println!("启动交互模式...");
}
interactive::run_interactive()
}