Commit bed2d627 authored by Christopher Silva's avatar Christopher Silva

add changes queue and macro for cell write functions

parent 5f7c0923
......@@ -32,6 +32,8 @@ fn main() {
}
}
sheet.process_changes();
let range = sheet.range(0, 0, 10, 10);
let sum = function::sum(range.clone());
let avg = function::avg(range.clone());
......@@ -49,15 +51,17 @@ fn main() {
println!("decimals: {} {} {} {} {} {}", dec, dec2, dec3, dec4, dec5, dec6);
sheet.write_formula(10, 10, "=sum(r0c0:r9c9)".to_string()).unwrap();
println!("range r10c10:r10c10: {:?}", sheet.render_range(10, 10, 1, 1));
println!("sum(r10c10:r10c10): {:?}", sheet.render_range(10, 10, 1, 1));
sheet.write_formula(10, 10, "=avg(r0c0:r9c9)".to_string()).unwrap();
println!("range r10c10:r10c10: {:?}", sheet.render_range(10, 10, 1, 1));
println!("avg(r10c10:r10c10): {:?}", sheet.render_range(10, 10, 1, 1));
sheet.write_formula(10, 10, "=count(r0c0:r9c9)".to_string()).unwrap();
println!("range r10c10:r10c10: {:?}", sheet.render_range(10, 10, 1, 1));
println!("count(r10c10:r10c10): {:?}", sheet.render_range(10, 10, 1, 1));
sheet.write_formula(10, 10, "=max(r0c0:r9c9)".to_string()).unwrap();
println!("range r10c10:r10c10: {:?}", sheet.render_range(10, 10, 1, 1));
println!("max(r10c10:r10c10): {:?}", sheet.render_range(10, 10, 1, 1));
sheet.write_formula(10, 10, "=min(r0c0:r9c9)".to_string()).unwrap();
println!("range r10c10:r10c10: {:?}", sheet.render_range(10, 10, 1, 1));
println!("min(r10c10:r10c10): {:?}", sheet.render_range(10, 10, 1, 1));
sheet.process_changes();
}
fn pow(x: Decimal, y: Decimal) -> Decimal {
......
......@@ -12,10 +12,33 @@ use crate::function;
pub type Range<'a> = Vec<Vec<Option<&'a Cell>>>;
pub type RenderedRange = Vec<Vec<String>>;
#[derive(Clone, Debug)]
enum Change {
Create((usize, usize), Cell),
Update((usize, usize), Cell),
Delete((usize, usize))
}
use Change::*;
#[derive(Clone, Debug)]
pub struct Sheet {
name: String,
cells: HashMap<(usize, usize), Cell>,
changes: Vec<Change>,
}
macro_rules! write_func {
($name:ident, $closure:expr) => {
pub fn $name(&mut self, r: usize, c: usize, value: String) -> Result<()> {
let cell = $closure(self, value)?;
self.changes.push(match self.cells.contains_key(&(r, c)) {
true => Update((r, c), cell.clone()),
false => Create((r, c), cell.clone()),
});
self.cells.insert((r, c), cell);
Ok(())
}
};
}
impl Sheet {
......@@ -23,6 +46,7 @@ impl Sheet {
Sheet {
name,
cells: HashMap::new(),
changes: Vec::new(),
}
}
......@@ -30,22 +54,36 @@ impl Sheet {
self.cells.len()
}
pub fn write_number(&mut self, r: usize, c: usize, value: String) -> Result<()> {
write_func!(write_number, |_sheet: &Sheet, value: String| -> Result<Cell> {
let decimal = Decimal::from_str(&value[..])?;
self.cells.insert((r, c), Number(decimal));
Ok(())
}
Ok(Number(decimal))
});
pub fn write_text(&mut self, r: usize, c: usize, value: String) {
self.cells.insert((r, c), Text(value));
}
write_func!(write_text, |_sheet: &Sheet, value: String| -> Result<Cell> {
Ok(Text(value))
});
pub fn write_formula(&mut self, r: usize, c: usize, value: String) -> Result<()> {
write_func!(write_formula, |sheet: &Sheet, value: String| -> Result<Cell> {
let call = formula::parse(value.clone())?;
let range = self.range(call.r, call.c, call.h, call.w);
let range = sheet.range(call.r, call.c, call.h, call.w);
let result = function::call(call.function, range);
self.cells.insert((r, c), Formula(value, Box::new(result)));
Ok(())
Ok(Formula(value, Box::new(result)))
});
pub fn delete_cell(&mut self, r: usize, c: usize) {
if let Some(_) = self.cells.remove(&(r, c)) {
self.changes.push(Delete((r, c)));
}
}
pub fn process_changes(&mut self) {
let changes = self.changes.clone();
self.changes = Vec::new();
println!("processing {} changes", changes.len());
// for change in changes {
// print!(".");
// }
println!("done");
}
pub fn range(&self, r: usize, c: usize, h: usize, w: usize) -> Range {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment