Skip to main content

excel_cli/cli/
common.rs

1use serde_json::Value;
2use std::path::Path;
3
4use crate::cli::error::AppError;
5use crate::cli::sheet_query::SheetBounds;
6use crate::excel::{Sheet, Workbook};
7use crate::utils::index_to_col_name;
8
9pub(crate) fn file_format(path: &Path) -> String {
10    path.extension()
11        .and_then(|extension| extension.to_str())
12        .map(str::to_lowercase)
13        .unwrap_or_else(|| "unknown".to_string())
14}
15
16pub(crate) fn format_range(
17    start_row: usize,
18    start_col: usize,
19    end_row: usize,
20    end_col: usize,
21) -> String {
22    format!(
23        "{}{}:{}{}",
24        index_to_col_name(start_col),
25        start_row,
26        index_to_col_name(end_col),
27        end_row
28    )
29}
30
31pub(crate) fn format_bounds(bounds: SheetBounds) -> String {
32    format_range(
33        bounds.start_row,
34        bounds.start_col,
35        bounds.end_row,
36        bounds.end_col,
37    )
38}
39
40pub(crate) fn value_text(value: &Value) -> String {
41    match value {
42        Value::Null => String::new(),
43        Value::String(value) => value.clone(),
44        other => other.to_string(),
45    }
46}
47
48pub(crate) fn tab_separated_values(values: &[Value]) -> String {
49    values.iter().map(value_text).collect::<Vec<_>>().join("\t")
50}
51
52pub(crate) fn sheet_by_index<'a>(
53    workbook: &'a Workbook,
54    sheet_index: usize,
55    sheet_name: &str,
56) -> Result<&'a Sheet, AppError> {
57    workbook
58        .get_sheet_by_index(sheet_index)
59        .ok_or_else(|| AppError::TargetNotFound {
60            message: format!("Sheet '{}' not found", sheet_name),
61        })
62}