Remove unneeded dependencies, start work on csv parsing
This commit is contained in:
121
Cargo.lock
generated
121
Cargo.lock
generated
@@ -23,7 +23,7 @@ version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
@@ -58,12 +58,6 @@ version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.23"
|
||||
@@ -112,54 +106,9 @@ dependencies = [
|
||||
"csv",
|
||||
"itertools",
|
||||
"nalgebra",
|
||||
"num-rational",
|
||||
"rayon",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
@@ -209,15 +158,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
@@ -270,15 +210,6 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.31.0"
|
||||
@@ -306,17 +237,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.1"
|
||||
@@ -343,7 +263,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
@@ -357,16 +276,6 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.12.0"
|
||||
@@ -433,28 +342,6 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
@@ -476,12 +363,6 @@ dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.137"
|
||||
|
||||
@@ -12,12 +12,9 @@ nalgebra = "0.31.0"
|
||||
# https://docs.rs/csv/1.1.6/csv/
|
||||
csv = "1.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
# simba = { version = "0.7.1", features = ["partial_fixed_point_support"] }
|
||||
|
||||
# num = "0.4"
|
||||
clap = { version = "3.1.18", features = ["derive"] }
|
||||
anyhow = "1.0"
|
||||
|
||||
itertools = "0.10.3"
|
||||
num-rational = "0.4.1"
|
||||
rayon = "1.6.1"
|
||||
@@ -88,9 +88,8 @@ pub fn move_money_2(
|
||||
initial_totals: HashMap<Unit, f64>,
|
||||
rules: &Vec<MovementRule>,
|
||||
) -> HashMap<Unit, f64> {
|
||||
// TODO: Should probably validate that all the rules have departments that actually exist in initial_totals.
|
||||
// Note: It's potentially a bit more intensive to use cloned totals, but it's much simpler code and, and since we're only working line-by-line
|
||||
// it isn't really that much memory. in practice
|
||||
// Note: It's potentially a bit more intensive to use cloned totals (rather than just update temp_total per rule),
|
||||
// but it's much simpler code and, and since we're only working line-by-line, it isn't really that much memory in practice
|
||||
let mut running_total = HashMap::from(initial_totals);
|
||||
let mut temp_total = running_total.clone();
|
||||
for rule in rules {
|
||||
@@ -135,11 +134,9 @@ pub enum DepartmentType {
|
||||
Overhead,
|
||||
}
|
||||
|
||||
// TODO: Could also look at BigDecimal rather than f64 for higher precision (even i64 might be fine if we don't need to divide...)
|
||||
// Note: remember these are overhead departments only when calculating the lu decomposition or pseudoinverse, and for each department,
|
||||
// you either need -1 or rest negative for a row to subtract the initial amounts so we end up effectively 0 (simultaneous equations end
|
||||
// up with negative there so yes this is expected)
|
||||
// Also, we could potentially use this same struct for non-overhead departments when mapping from overhead to
|
||||
pub struct OverheadAllocationRule {
|
||||
from_overhead_department: String,
|
||||
to_department: String,
|
||||
|
||||
89
src/main.rs
89
src/main.rs
@@ -1,6 +1,7 @@
|
||||
use std::{error::Error, io::Write, path::PathBuf};
|
||||
use std::{collections::HashMap, error::Error, io::Write, path::PathBuf};
|
||||
|
||||
use clap::{builder::PathBufValueParser, Parser, Subcommand};
|
||||
use coster_rs::Unit;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Parser)]
|
||||
@@ -47,7 +48,6 @@ enum Commands {
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: Return error (implement the required trait to allow an error to be returned)
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
@@ -57,23 +57,67 @@ fn main() -> anyhow::Result<()> {
|
||||
lines,
|
||||
output,
|
||||
} => move_money(rules, lines, output),
|
||||
Commands::smush_rules { rules, output } => smush_rules(rules, output)?,
|
||||
Commands::smush_rules { rules, output } => smush_rules(rules, output),
|
||||
Commands::allocate_overheads {
|
||||
rules,
|
||||
lines,
|
||||
output,
|
||||
} => allocate_overheads(rules, lines, output)?,
|
||||
};
|
||||
Ok(())
|
||||
} => allocate_overheads(rules, lines, output),
|
||||
}
|
||||
}
|
||||
|
||||
fn move_money(rules: PathBuf, lines: PathBuf, output: Option<PathBuf>) {
|
||||
// read rules into required struct (basically map each line into an array)
|
||||
fn move_money(rules: PathBuf, lines: PathBuf, output: Option<PathBuf>) -> anyhow::Result<()> {
|
||||
let mut rdr = csv::Reader::from_path(lines)?;
|
||||
let headers = rdr.headers()?;
|
||||
let mut account_index = 0;
|
||||
let mut department_index = 0;
|
||||
for (index, field) in headers.iter().enumerate() {
|
||||
if field == "Account" {
|
||||
account_index = index;
|
||||
} else if field == "Department" {
|
||||
department_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
let lines: HashMap<Unit, f64> = rdr
|
||||
.records()
|
||||
.map(|record| {
|
||||
let record = record.unwrap();
|
||||
let account = record.get(account_index).unwrap();
|
||||
let department = record.get(department_index).unwrap();
|
||||
let sum = record
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(i, _)| *i != account_index && *i != department_index)
|
||||
.map(|(_, f)| f.parse::<f64>().unwrap())
|
||||
.sum();
|
||||
(
|
||||
Unit {
|
||||
account: account.into(),
|
||||
department: department.into(),
|
||||
},
|
||||
sum,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// read rules into required struct (basically map each line into an array). Need to figure out the input format...
|
||||
let mut rdr = csv::Reader::from_path(rules)?;
|
||||
for result in rdr.deserialize() {
|
||||
let record: CsvMovementRule = result?;
|
||||
// TODO: Problem is the from/to are ranges, that rely on the gl data, so need to get a list of
|
||||
//
|
||||
}
|
||||
|
||||
// Read gl lines data (all of it). For each line, sum the periods, and insert the summed
|
||||
// line into a hashmap (need to read the whole gl in as we can move between every line)
|
||||
// We use a record, everything that's not an account/department is assumed to be a period
|
||||
|
||||
// Then run move_moeny, and output the result into a new file at the given output location
|
||||
// Then run move_moeny
|
||||
|
||||
// Ouput the list moved moneys
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn smush_rules(rules_path: PathBuf, output: Option<PathBuf>) -> anyhow::Result<()> {
|
||||
@@ -86,14 +130,15 @@ fn allocate_overheads(
|
||||
output: Option<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut rdr = csv::Reader::from_path(rules_path)?;
|
||||
|
||||
for result in rdr.deserialize() {
|
||||
let record: CsvMovementRule = result?;
|
||||
let record: CsvOverheadAllocationRule = result?;
|
||||
}
|
||||
|
||||
let mut account_reader = csv::Reader::from_path(lines)?;
|
||||
|
||||
for result in account_reader.deserialize() {
|
||||
let record: CsvAccountCost = result?;
|
||||
let record: CsvCost = result?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -101,15 +146,31 @@ fn allocate_overheads(
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct CsvMovementRule {
|
||||
from_department: String,
|
||||
to_department: String,
|
||||
#[serde(rename = "FromCC")]
|
||||
// Need strings to further split later
|
||||
from_departments: String,
|
||||
to_departments: String,
|
||||
all_from_departments: bool,
|
||||
all_to_departments: bool,
|
||||
from_accounts: String,
|
||||
to_accounts: String,
|
||||
all_from_accounts: bool,
|
||||
all_to_accounts: bool,
|
||||
amount: f64,
|
||||
is_percent: Option<bool>,
|
||||
is_separator: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct CsvAccountCost {
|
||||
struct CsvOverheadAllocationRule {
|
||||
from_overhead_department: String,
|
||||
to_department: String,
|
||||
percent: f64,
|
||||
to_department_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct CsvCost {
|
||||
account: String,
|
||||
department: String,
|
||||
value: f64,
|
||||
|
||||
Reference in New Issue
Block a user