committed by
GitHub
parent
1381533b9c
commit
0029901ca3
18
.github/workflows/publish-wiki.yml
vendored
Normal file
18
.github/workflows/publish-wiki.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: Publish wiki
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- wiki/**
|
||||||
|
- .github/workflows/publish-wiki.yml
|
||||||
|
concurrency:
|
||||||
|
group: publish-wiki
|
||||||
|
cancel-in-progress: true
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
jobs:
|
||||||
|
publish-wiki:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Andrew-Chen-Wang/github-wiki-action@v4
|
||||||
3
Makefile
3
Makefile
@@ -8,6 +8,8 @@ format:
|
|||||||
tests: lint
|
tests: lint
|
||||||
cargo test
|
cargo test
|
||||||
make remove-xlsx
|
make remove-xlsx
|
||||||
|
./target/debug/documentation
|
||||||
|
cmp functions.md wiki/functions.md || exit 1
|
||||||
|
|
||||||
remove-xlsx:
|
remove-xlsx:
|
||||||
rm -f xlsx/hello-calc.xlsx
|
rm -f xlsx/hello-calc.xlsx
|
||||||
@@ -21,6 +23,7 @@ clean: remove-xlsx
|
|||||||
rm -f cargo-test-*
|
rm -f cargo-test-*
|
||||||
rm -f base/cargo-test-*
|
rm -f base/cargo-test-*
|
||||||
rm -f xlsx/cargo-test-*
|
rm -f xlsx/cargo-test-*
|
||||||
|
rm functions.md
|
||||||
|
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
use std::array::IntoIter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_result::CalcResult,
|
calc_result::CalcResult,
|
||||||
@@ -244,6 +245,206 @@ pub enum Function {
|
|||||||
Subtotal,
|
Subtotal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Function {
|
||||||
|
pub fn into_iter() -> IntoIter<Function, 192> {
|
||||||
|
[
|
||||||
|
Function::And,
|
||||||
|
Function::False,
|
||||||
|
Function::If,
|
||||||
|
Function::Iferror,
|
||||||
|
Function::Ifna,
|
||||||
|
Function::Ifs,
|
||||||
|
Function::Not,
|
||||||
|
Function::Or,
|
||||||
|
Function::Switch,
|
||||||
|
Function::True,
|
||||||
|
Function::Xor,
|
||||||
|
Function::Sin,
|
||||||
|
Function::Cos,
|
||||||
|
Function::Tan,
|
||||||
|
Function::Asin,
|
||||||
|
Function::Acos,
|
||||||
|
Function::Atan,
|
||||||
|
Function::Sinh,
|
||||||
|
Function::Cosh,
|
||||||
|
Function::Tanh,
|
||||||
|
Function::Asinh,
|
||||||
|
Function::Acosh,
|
||||||
|
Function::Atanh,
|
||||||
|
Function::Abs,
|
||||||
|
Function::Pi,
|
||||||
|
Function::Sqrt,
|
||||||
|
Function::Sqrtpi,
|
||||||
|
Function::Atan2,
|
||||||
|
Function::Power,
|
||||||
|
Function::Max,
|
||||||
|
Function::Min,
|
||||||
|
Function::Product,
|
||||||
|
Function::Rand,
|
||||||
|
Function::Randbetween,
|
||||||
|
Function::Round,
|
||||||
|
Function::Rounddown,
|
||||||
|
Function::Roundup,
|
||||||
|
Function::Sum,
|
||||||
|
Function::Sumif,
|
||||||
|
Function::Sumifs,
|
||||||
|
Function::Choose,
|
||||||
|
Function::Column,
|
||||||
|
Function::Columns,
|
||||||
|
Function::Index,
|
||||||
|
Function::Indirect,
|
||||||
|
Function::Hlookup,
|
||||||
|
Function::Lookup,
|
||||||
|
Function::Match,
|
||||||
|
Function::Offset,
|
||||||
|
Function::Row,
|
||||||
|
Function::Rows,
|
||||||
|
Function::Vlookup,
|
||||||
|
Function::Xlookup,
|
||||||
|
Function::Concatenate,
|
||||||
|
Function::Exact,
|
||||||
|
Function::Value,
|
||||||
|
Function::T,
|
||||||
|
Function::Valuetotext,
|
||||||
|
Function::Concat,
|
||||||
|
Function::Find,
|
||||||
|
Function::Left,
|
||||||
|
Function::Len,
|
||||||
|
Function::Lower,
|
||||||
|
Function::Mid,
|
||||||
|
Function::Right,
|
||||||
|
Function::Search,
|
||||||
|
Function::Text,
|
||||||
|
Function::Trim,
|
||||||
|
Function::Upper,
|
||||||
|
Function::Isnumber,
|
||||||
|
Function::Isnontext,
|
||||||
|
Function::Istext,
|
||||||
|
Function::Islogical,
|
||||||
|
Function::Isblank,
|
||||||
|
Function::Iserr,
|
||||||
|
Function::Iserror,
|
||||||
|
Function::Isna,
|
||||||
|
Function::Na,
|
||||||
|
Function::Isref,
|
||||||
|
Function::Isodd,
|
||||||
|
Function::Iseven,
|
||||||
|
Function::ErrorType,
|
||||||
|
Function::Isformula,
|
||||||
|
Function::Type,
|
||||||
|
Function::Sheet,
|
||||||
|
Function::Average,
|
||||||
|
Function::Averagea,
|
||||||
|
Function::Averageif,
|
||||||
|
Function::Averageifs,
|
||||||
|
Function::Count,
|
||||||
|
Function::Counta,
|
||||||
|
Function::Countblank,
|
||||||
|
Function::Countif,
|
||||||
|
Function::Countifs,
|
||||||
|
Function::Maxifs,
|
||||||
|
Function::Minifs,
|
||||||
|
Function::Year,
|
||||||
|
Function::Day,
|
||||||
|
Function::Month,
|
||||||
|
Function::Eomonth,
|
||||||
|
Function::Date,
|
||||||
|
Function::Edate,
|
||||||
|
Function::Today,
|
||||||
|
Function::Now,
|
||||||
|
Function::Pmt,
|
||||||
|
Function::Pv,
|
||||||
|
Function::Rate,
|
||||||
|
Function::Nper,
|
||||||
|
Function::Fv,
|
||||||
|
Function::Ppmt,
|
||||||
|
Function::Ipmt,
|
||||||
|
Function::Npv,
|
||||||
|
Function::Mirr,
|
||||||
|
Function::Irr,
|
||||||
|
Function::Xirr,
|
||||||
|
Function::Xnpv,
|
||||||
|
Function::Rept,
|
||||||
|
Function::Textafter,
|
||||||
|
Function::Textbefore,
|
||||||
|
Function::Textjoin,
|
||||||
|
Function::Substitute,
|
||||||
|
Function::Ispmt,
|
||||||
|
Function::Rri,
|
||||||
|
Function::Sln,
|
||||||
|
Function::Syd,
|
||||||
|
Function::Nominal,
|
||||||
|
Function::Effect,
|
||||||
|
Function::Pduration,
|
||||||
|
Function::Tbillyield,
|
||||||
|
Function::Tbillprice,
|
||||||
|
Function::Tbilleq,
|
||||||
|
Function::Dollarde,
|
||||||
|
Function::Dollarfr,
|
||||||
|
Function::Ddb,
|
||||||
|
Function::Db,
|
||||||
|
Function::Cumprinc,
|
||||||
|
Function::Cumipmt,
|
||||||
|
Function::Besseli,
|
||||||
|
Function::Besselj,
|
||||||
|
Function::Besselk,
|
||||||
|
Function::Bessely,
|
||||||
|
Function::Erf,
|
||||||
|
Function::ErfPrecise,
|
||||||
|
Function::Erfc,
|
||||||
|
Function::ErfcPrecise,
|
||||||
|
Function::Bin2dec,
|
||||||
|
Function::Bin2hex,
|
||||||
|
Function::Bin2oct,
|
||||||
|
Function::Dec2Bin,
|
||||||
|
Function::Dec2hex,
|
||||||
|
Function::Dec2oct,
|
||||||
|
Function::Hex2bin,
|
||||||
|
Function::Hex2dec,
|
||||||
|
Function::Hex2oct,
|
||||||
|
Function::Oct2bin,
|
||||||
|
Function::Oct2dec,
|
||||||
|
Function::Oct2hex,
|
||||||
|
Function::Bitand,
|
||||||
|
Function::Bitlshift,
|
||||||
|
Function::Bitor,
|
||||||
|
Function::Bitrshift,
|
||||||
|
Function::Bitxor,
|
||||||
|
Function::Complex,
|
||||||
|
Function::Imabs,
|
||||||
|
Function::Imaginary,
|
||||||
|
Function::Imargument,
|
||||||
|
Function::Imconjugate,
|
||||||
|
Function::Imcos,
|
||||||
|
Function::Imcosh,
|
||||||
|
Function::Imcot,
|
||||||
|
Function::Imcsc,
|
||||||
|
Function::Imcsch,
|
||||||
|
Function::Imdiv,
|
||||||
|
Function::Imexp,
|
||||||
|
Function::Imln,
|
||||||
|
Function::Imlog10,
|
||||||
|
Function::Imlog2,
|
||||||
|
Function::Impower,
|
||||||
|
Function::Improduct,
|
||||||
|
Function::Imreal,
|
||||||
|
Function::Imsec,
|
||||||
|
Function::Imsech,
|
||||||
|
Function::Imsin,
|
||||||
|
Function::Imsinh,
|
||||||
|
Function::Imsqrt,
|
||||||
|
Function::Imsub,
|
||||||
|
Function::Imsum,
|
||||||
|
Function::Imtan,
|
||||||
|
Function::Convert,
|
||||||
|
Function::Delta,
|
||||||
|
Function::Gestep,
|
||||||
|
Function::Subtotal,
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
/// Some functions in Excel like CONCAT are stringified as `_xlfn.CONCAT`.
|
/// Some functions in Excel like CONCAT are stringified as `_xlfn.CONCAT`.
|
||||||
pub fn to_xlsx_string(&self) -> String {
|
pub fn to_xlsx_string(&self) -> String {
|
||||||
@@ -708,7 +909,23 @@ impl fmt::Display for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Documentation for one function
|
||||||
|
pub struct Documentation {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
/// Produces documentation for all implemented functions
|
||||||
|
pub fn documentation() -> Vec<Documentation> {
|
||||||
|
let mut doc = Vec::new();
|
||||||
|
for function in Function::into_iter() {
|
||||||
|
doc.push(Documentation {
|
||||||
|
name: function.to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
doc
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn evaluate_function(
|
pub(crate) fn evaluate_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
kind: &Function,
|
kind: &Function,
|
||||||
@@ -928,3 +1145,66 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::functions::Function;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_iterator() {
|
||||||
|
// This checks that the number of functions in the enum is the same
|
||||||
|
// as the number of functions in the Iterator.
|
||||||
|
|
||||||
|
// This is tricky. In Rust we cannot loop over all the members of an enum.
|
||||||
|
// There are alternatives like using an external crate like strum.
|
||||||
|
// But I am not in the mood for that.
|
||||||
|
|
||||||
|
// What we do here is read this file , extract the functions in the enum
|
||||||
|
// and check they are the same as in the iterator
|
||||||
|
let file = File::open("src/functions/mod.rs").unwrap();
|
||||||
|
let reader = BufReader::new(file);
|
||||||
|
let mut start = false;
|
||||||
|
let mut list = Vec::new();
|
||||||
|
|
||||||
|
for line in reader.lines() {
|
||||||
|
let text = line.unwrap();
|
||||||
|
let text = text.trim().trim_end_matches(',');
|
||||||
|
if text == "pub enum Function {" {
|
||||||
|
start = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if start {
|
||||||
|
if text == "}" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if text.starts_with("//") {
|
||||||
|
// skip comments
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if text.is_empty() {
|
||||||
|
// skip empty lines
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
list.push(text.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We make a list with their functions names, but we escape ".": ERROR.TYPE => ERRORTYPE
|
||||||
|
let iter_list = Function::into_iter()
|
||||||
|
.map(|f| format!("{}", f).replace('.', ""))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let len = iter_list.len();
|
||||||
|
|
||||||
|
assert_eq!(list.len(), len);
|
||||||
|
// We still need to check there are no duplicates. This will fail if a function in iter_list
|
||||||
|
// is included twice and one is missing
|
||||||
|
for function in list {
|
||||||
|
assert!(iter_list.contains(&function.to_uppercase()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
192
wiki/functions.md
Normal file
192
wiki/functions.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
AND
|
||||||
|
FALSE
|
||||||
|
IF
|
||||||
|
IFERROR
|
||||||
|
IFNA
|
||||||
|
IFS
|
||||||
|
NOT
|
||||||
|
OR
|
||||||
|
SWITCH
|
||||||
|
TRUE
|
||||||
|
XOR
|
||||||
|
SIN
|
||||||
|
COS
|
||||||
|
TAN
|
||||||
|
ASIN
|
||||||
|
ACOS
|
||||||
|
ATAN
|
||||||
|
SINH
|
||||||
|
COSH
|
||||||
|
TANH
|
||||||
|
ASINH
|
||||||
|
ACOSH
|
||||||
|
ATANH
|
||||||
|
ABS
|
||||||
|
PI
|
||||||
|
SQRT
|
||||||
|
SQRTPI
|
||||||
|
ATAN2
|
||||||
|
POWER
|
||||||
|
MAX
|
||||||
|
MIN
|
||||||
|
PRODUCT
|
||||||
|
RAND
|
||||||
|
RANDBETWEEN
|
||||||
|
ROUND
|
||||||
|
ROUNDDOWN
|
||||||
|
ROUNDUP
|
||||||
|
SUM
|
||||||
|
SUMIF
|
||||||
|
SUMIFS
|
||||||
|
CHOOSE
|
||||||
|
COLUMN
|
||||||
|
COLUMNS
|
||||||
|
INDEX
|
||||||
|
INDIRECT
|
||||||
|
HLOOKUP
|
||||||
|
LOOKUP
|
||||||
|
MATCH
|
||||||
|
OFFSET
|
||||||
|
ROW
|
||||||
|
ROWS
|
||||||
|
VLOOKUP
|
||||||
|
XLOOKUP
|
||||||
|
CONCATENATE
|
||||||
|
EXACT
|
||||||
|
VALUE
|
||||||
|
T
|
||||||
|
VALUETOTEXT
|
||||||
|
CONCAT
|
||||||
|
FIND
|
||||||
|
LEFT
|
||||||
|
LEN
|
||||||
|
LOWER
|
||||||
|
MID
|
||||||
|
RIGHT
|
||||||
|
SEARCH
|
||||||
|
TEXT
|
||||||
|
TRIM
|
||||||
|
UPPER
|
||||||
|
ISNUMBER
|
||||||
|
ISNONTEXT
|
||||||
|
ISTEXT
|
||||||
|
ISLOGICAL
|
||||||
|
ISBLANK
|
||||||
|
ISERR
|
||||||
|
ISERROR
|
||||||
|
ISNA
|
||||||
|
NA
|
||||||
|
ISREF
|
||||||
|
ISODD
|
||||||
|
ISEVEN
|
||||||
|
ERROR.TYPE
|
||||||
|
ISFORMULA
|
||||||
|
TYPE
|
||||||
|
SHEET
|
||||||
|
AVERAGE
|
||||||
|
AVERAGEA
|
||||||
|
AVERAGEIF
|
||||||
|
AVERAGEIFS
|
||||||
|
COUNT
|
||||||
|
COUNTA
|
||||||
|
COUNTBLANK
|
||||||
|
COUNTIF
|
||||||
|
COUNTIFS
|
||||||
|
MAXIFS
|
||||||
|
MINIFS
|
||||||
|
YEAR
|
||||||
|
DAY
|
||||||
|
MONTH
|
||||||
|
EOMONTH
|
||||||
|
DATE
|
||||||
|
EDATE
|
||||||
|
TODAY
|
||||||
|
NOW
|
||||||
|
PMT
|
||||||
|
PV
|
||||||
|
RATE
|
||||||
|
NPER
|
||||||
|
FV
|
||||||
|
PPMT
|
||||||
|
IPMT
|
||||||
|
NPV
|
||||||
|
MIRR
|
||||||
|
IRR
|
||||||
|
XIRR
|
||||||
|
XNPV
|
||||||
|
REPT
|
||||||
|
TEXTAFTER
|
||||||
|
TEXTBEFORE
|
||||||
|
TEXTJOIN
|
||||||
|
SUBSTITUTE
|
||||||
|
ISPMT
|
||||||
|
RRI
|
||||||
|
SLN
|
||||||
|
SYD
|
||||||
|
NOMINAL
|
||||||
|
EFFECT
|
||||||
|
PDURATION
|
||||||
|
TBILLYIELD
|
||||||
|
TBILLPRICE
|
||||||
|
TBILLEQ
|
||||||
|
DOLLARDE
|
||||||
|
DOLLARFR
|
||||||
|
DDB
|
||||||
|
DB
|
||||||
|
CUMPRINC
|
||||||
|
CUMIPMT
|
||||||
|
BESSELI
|
||||||
|
BESSELJ
|
||||||
|
BESSELK
|
||||||
|
BESSELY
|
||||||
|
ERF
|
||||||
|
ERF.PRECISE
|
||||||
|
ERFC
|
||||||
|
ERFC.PRECISE
|
||||||
|
BIN2DEC
|
||||||
|
BIN2HEX
|
||||||
|
BIN2OCT
|
||||||
|
DEC2BIN
|
||||||
|
DEC2HEX
|
||||||
|
DEC2OCT
|
||||||
|
HEX2BIN
|
||||||
|
HEX2DEC
|
||||||
|
HEX2OCT
|
||||||
|
OCT2BIN
|
||||||
|
OCT2DEC
|
||||||
|
OCT2HEX
|
||||||
|
BITAND
|
||||||
|
BITLSHIFT
|
||||||
|
BITOR
|
||||||
|
BITRSHIFT
|
||||||
|
BITXOR
|
||||||
|
COMPLEX
|
||||||
|
IMABS
|
||||||
|
IMAGINARY
|
||||||
|
IMARGUMENT
|
||||||
|
IMCONJUGATE
|
||||||
|
IMCOS
|
||||||
|
IMCOSH
|
||||||
|
IMCOT
|
||||||
|
IMCSC
|
||||||
|
IMCSCH
|
||||||
|
IMDIV
|
||||||
|
IMEXP
|
||||||
|
IMLN
|
||||||
|
IMLOG10
|
||||||
|
IMLOG2
|
||||||
|
IMPOWER
|
||||||
|
IMPRODUCT
|
||||||
|
IMREAL
|
||||||
|
IMSEC
|
||||||
|
IMSECH
|
||||||
|
IMSIN
|
||||||
|
IMSINH
|
||||||
|
IMSQRT
|
||||||
|
IMSUB
|
||||||
|
IMSUM
|
||||||
|
IMTAN
|
||||||
|
CONVERT
|
||||||
|
DELTA
|
||||||
|
GESTEP
|
||||||
|
SUBTOTAL
|
||||||
@@ -34,3 +34,8 @@ path = "src/lib.rs"
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "test"
|
name = "test"
|
||||||
path = "src/bin/test.rs"
|
path = "src/bin/test.rs"
|
||||||
|
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "documentation"
|
||||||
|
path = "src/bin/documentation.rs"
|
||||||
17
xlsx/src/bin/documentation.rs
Normal file
17
xlsx/src/bin/documentation.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//! Produces documentation of all the implemented IronCalc functions
|
||||||
|
//! and saves the result to functions.md
|
||||||
|
//!
|
||||||
|
//! Usage: documentation
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use ironcalc_base::model::Model;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut doc = Vec::new();
|
||||||
|
for function in Model::documentation() {
|
||||||
|
doc.push(function.name);
|
||||||
|
}
|
||||||
|
let data = doc.join("\n");
|
||||||
|
fs::write("functions.md", data).expect("Unable to write file");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user