mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-29 13:16:50 -06:00
56 lines
1.7 KiB
Rust
56 lines
1.7 KiB
Rust
//! Formula text conversion between the model (canonical text, no `=`) and files (`_xlfn.`
|
|
//! prefixes for newer functions).
|
|
|
|
use gridcraft_formula::Expr;
|
|
use gridcraft_model::Formula;
|
|
|
|
/// Formula text for a file.
|
|
pub fn to_file(f: &Formula) -> String {
|
|
match f.expr() {
|
|
Some(e) => expr_to_file(e),
|
|
None => f.text.clone(),
|
|
}
|
|
}
|
|
|
|
/// Arbitrary formula text (names, CF, validation) for a file. Unparseable text is kept.
|
|
pub fn text_to_file(text: &str) -> String {
|
|
let body = text.strip_prefix('=').unwrap_or(text);
|
|
match gridcraft_formula::parse(body) {
|
|
Ok(e) => expr_to_file(e),
|
|
Err(_) => body.to_string(),
|
|
}
|
|
}
|
|
|
|
fn expr_to_file(e: Expr) -> String {
|
|
let e = e.map(&mut |x| match x {
|
|
Expr::Call(name, args) => match crate::tables::file_function_name(&name) {
|
|
Some(n) => Expr::Call(n, args),
|
|
None => Expr::Call(name, args),
|
|
},
|
|
other => other,
|
|
});
|
|
gridcraft_formula::print(&e)
|
|
}
|
|
|
|
/// Formula text read from a file → model text (strips prefixes when it parses).
|
|
pub fn from_file(text: &str) -> String {
|
|
let body = text.strip_prefix('=').unwrap_or(text);
|
|
match gridcraft_formula::parse(body) {
|
|
Ok(e) => gridcraft_formula::print(&e),
|
|
Err(_) => body.to_string(),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn prefixes() {
|
|
assert_eq!(to_file(&Formula::new("XLOOKUP(1,A:A,B:B)+SUM(A1)")), "_xlfn.XLOOKUP(1,A:A,B:B)+SUM(A1)");
|
|
assert_eq!(to_file(&Formula::new("FILTER(A1:A3,B1:B3)")), "_xlfn._xlws.FILTER(A1:A3,B1:B3)");
|
|
assert_eq!(from_file("_xlfn.XLOOKUP(1,A:A,B:B)"), "XLOOKUP(1,A:A,B:B)");
|
|
assert_eq!(text_to_file("=IFS(A1>0,1)"), "_xlfn.IFS(A1>0,1)");
|
|
}
|
|
}
|