csvx 0.1.17

Comma-Separated Values eXtended
Documentation
use super::*;

pub struct Node {
    x: Box<ThreadSafeNode>,
    y: Box<ThreadSafeNode>,
    old_dependent: Option<(usize, usize)>,
}

impl super::Node for Node {
    fn new(seqs: Vec<Vec<Token>>) -> (Box<ThreadSafeNode>, Vec<(usize, usize)>) {
        let (x, mut x_refs) = parse(&seqs[0]);
        let (y, mut y_refs) = parse(&seqs[1]);
        x_refs.append(&mut y_refs);
        (
            Box::new(Self {
                x,
                y,
                old_dependent: None,
            }),
            x_refs,
        )
    }
    fn calc(
        &mut self,
        calculated_table: &Vec<Vec<Value>>,
    ) -> (Value, Vec<(usize, usize)>, Vec<(usize, usize)>) {
        let mut x = self.x.calc(calculated_table);
        let mut y = self.y.calc(calculated_table);

        if let Some(old_dependent) = self.old_dependent {
            x.1.push(old_dependent);
        }
        x.1.append(&mut y.1);
        x.2.append(&mut y.2);

        let value = match (x.0, y.0) {
            (Value::Integer(dependent_x), Value::Integer(dependent_y)) => {
                if 0 <= dependent_y
                    && (dependent_y as usize) < calculated_table.len()
                    && 0 <= dependent_x
                    && (dependent_x as usize) < calculated_table[dependent_y as usize].len()
                {
                    let dependent_x = dependent_x as usize;
                    let dependent_y = dependent_y as usize;

                    x.2.push((dependent_x, dependent_y));
                    self.old_dependent = Some((dependent_x, dependent_y));

                    calculated_table[dependent_y][dependent_x].clone()
                } else {
                    self.old_dependent = None;
                    Value::Error
                }
            }
            _ => {
                self.old_dependent = None;
                Value::Error
            }
        };

        (value, x.1, x.2)
    }
}