1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/// Convert a zero indexed column cell reference to a string like `"A"`.
///
/// Utility function to convert a zero based column reference to a string
/// representation. This can be useful when constructing ranges for formulas.
///
/// # Examples:
///
/// ```
/// use rsheet_lib::cells::column_number_to_name;
///
/// assert_eq!(column_number_to_name(0), "A");
/// assert_eq!(column_number_to_name(1), "B");
/// assert_eq!(column_number_to_name(702), "AAA");
/// ```
///
/// Source: [rust_xlsxwriter].
///
/// [rust_xlsxwriter]: https://docs.rs/rust_xlsxwriter/latest/src/rust_xlsxwriter/utility.rs.html#97-105
///
pub fn column_number_to_name(col_num: u32) -> String {
let mut col_name_reversed = String::new();
let mut col_num = col_num + 1;
while col_num > 0 {
// Set remainder from 1 .. 26
let mut remainder = col_num % 26;
if remainder == 0 {
remainder = 26;
}
// Convert the remainder to a character.
let col_letter = char::from_u32('A' as u32 - 1 + remainder).unwrap();
// Accumulate the column letters, right to left.
col_name_reversed.push(col_letter);
// Get the next order of magnitude.
col_num = (col_num - 1) / 26;
}
col_name_reversed.chars().rev().collect()
}
/// Convert a column string such as `"A"` to a zero indexed column reference.
///
/// Utility function to convert a column string representation to a zero based
/// column reference.
///
/// # Examples:
///
/// ```
/// use rsheet_lib::cells::column_name_to_number;
///
/// assert_eq!(column_name_to_number("A"), 0);
/// assert_eq!(column_name_to_number("B"), 1);
/// assert_eq!(column_name_to_number("AAA"), 702);
/// ```
///
pub fn column_name_to_number(column: &str) -> u32 {
assert!(column.is_ascii());
let mut col_num = 0;
for char in column.chars() {
col_num = (col_num * 26) + (char as u32 - 'A' as u32 + 1);
}
col_num - 1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_column_number_to_name() {
assert_eq!(column_number_to_name(0), "A");
assert_eq!(column_number_to_name(1), "B");
assert_eq!(column_number_to_name(25), "Z");
assert_eq!(column_number_to_name(26), "AA");
assert_eq!(column_number_to_name(27), "AB");
assert_eq!(column_number_to_name(51), "AZ");
assert_eq!(column_number_to_name(52), "BA");
assert_eq!(column_number_to_name(53), "BB");
assert_eq!(column_number_to_name(701), "ZZ");
assert_eq!(column_number_to_name(702), "AAA");
assert_eq!(column_number_to_name(703), "AAB");
}
#[test]
fn test_column_name_to_number() {
assert_eq!(column_name_to_number("A"), 0);
assert_eq!(column_name_to_number("B"), 1);
assert_eq!(column_name_to_number("Z"), 25);
assert_eq!(column_name_to_number("AA"), 26);
assert_eq!(column_name_to_number("AB"), 27);
assert_eq!(column_name_to_number("AZ"), 51);
assert_eq!(column_name_to_number("BA"), 52);
assert_eq!(column_name_to_number("BB"), 53);
assert_eq!(column_name_to_number("ZZ"), 701);
assert_eq!(column_name_to_number("AAA"), 702);
assert_eq!(column_name_to_number("AAB"), 703);
}
}