fn process_collected_raw_data()

in src/data/interrupts.rs [136:227]


fn process_collected_raw_data(buffer: Data) -> Result<ProcessedData> {
    let mut interrupt_data = InterruptData::new();
    let raw_value = match buffer {
        Data::InterruptDataRaw(ref value) => value,
        _ => panic!("Invalid Data type in raw file"),
    };
    let mut reader = BufReader::new(raw_value.data.as_bytes());

    /* Collect the CPUs from the 1st line */
    let mut cpus_string = String::new();
    reader.read_line(&mut cpus_string)?;
    let cpus = cpus_string.split_whitespace();

    /* Create a vec to hold CPU # to be use later */
    let cpus_nr: Vec<u64> = cpus
        .into_iter()
        .map(|string| string[3..].parse::<u64>().unwrap())
        .collect();
    let cpu_count = cpus_nr.len() as u64;

    let mut interrupt_line_datas = Vec::new();
    for line in reader.lines() {
        let mut interrupt_line_data = InterruptLineData::new();
        interrupt_line_data.set_time(raw_value.time);

        let line = line?;
        let mut split = line
            .split(|c: char| c.is_whitespace() || c == ':')
            .filter(|s| !s.is_empty());

        /* Get type of interrupt line */
        let intr_line = get_intr_line(split.next().unwrap())?;
        interrupt_line_data.set_interrupt_line(intr_line.clone());

        match intr_line {
            InterruptLine::InterruptStr(ref value) => {
                /* Interrupts of type MIS/ERR are not per cpu */
                if value.to_uppercase() == "MIS" || value.to_uppercase() == "ERR" {
                    let interrupt_cpu_data = get_interrupt_cpu_data(split.next().unwrap(), 0)?;
                    interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
                    interrupt_line_data.set_type(value.to_string());
                } else {
                    /* Other named INTRs are per-cpu */
                    for cpu in 0..cpu_count {
                        let interrupt_cpu_data = get_interrupt_cpu_data(
                            split.next().unwrap(),
                            *cpus_nr.get(cpu as usize).unwrap(),
                        )?;
                        interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
                    }
                    /*
                     * Their names can contain spaces. Use this until as_str is
                     * merged and available in stable Rust.
                     * https://github.com/rust-lang/rust/issues/77998
                     *
                     * as_str - Get the remaining data as is
                     */
                    let mut type_name = Vec::<&str>::new();
                    loop {
                        let s = split.next();
                        match s {
                            Some(value) => type_name.push(value),
                            None => break,
                        }
                    }
                    interrupt_line_data.set_type(type_name.join(" ").to_string());
                }
            }
            InterruptLine::InterruptNr(_) => {
                /* Numbered interrupt lines are per-cpu */
                for cpu in 0..cpu_count {
                    let interrupt_cpu_data = get_interrupt_cpu_data(
                        split.next().unwrap(),
                        *cpus_nr.get(cpu as usize).unwrap(),
                    )?;
                    interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
                }
                /* They also contain additional information about type, edge and device name */
                let intr_type = split.next().unwrap();
                let device_name = split.last().unwrap();
                interrupt_line_data.set_type(intr_type.to_string());
                interrupt_line_data.set_device(device_name.to_string());
            }
            _ => error!("Invalid interrupt type"),
        }
        interrupt_line_datas.push(interrupt_line_data);
    }
    trace!("{:#?}", interrupt_line_datas);
    interrupt_data.set_interrupt_data(interrupt_line_datas);
    let processed_data = ProcessedData::InterruptData(interrupt_data);
    Ok(processed_data)
}