use crate::{
Exceptions,
common::Result,
oned::{OneDReader, one_d_reader},
};
pub trait AbstractRSSReaderTrait: OneDReader {
const MAX_AVG_VARIANCE: f32 = 0.2;
const MAX_INDIVIDUAL_VARIANCE: f32 = 0.45;
const MIN_FINDER_PATTERN_RATIO: f32 = 9.5 / 12.0;
const MAX_FINDER_PATTERN_RATIO: f32 = 12.5 / 14.0;
fn parseFinderValue<const N: usize>(
counters: &[u32; N],
finderPatterns: &[[u32; N]],
) -> Result<u32> {
for (value, pattern) in finderPatterns.iter().enumerate() {
if one_d_reader::pattern_match_variance(
counters,
pattern,
Self::MAX_INDIVIDUAL_VARIANCE,
) < Self::MAX_AVG_VARIANCE
{
return Ok(value as u32);
}
}
Err(Exceptions::NOT_FOUND)
}
fn increment(array: &mut [u32], errors: &[f32]) {
let mut index = 0;
let mut biggestError = errors[0];
for (i, error) in errors.iter().enumerate().take(array.len()).skip(1) {
if *error > biggestError {
biggestError = *error;
index = i;
}
}
array[index] += 1;
}
fn decrement(array: &mut [u32], errors: &[f32]) {
let mut index = 0;
let mut biggestError = errors[0];
for (i, error) in errors.iter().enumerate().take(array.len()).skip(1) {
if *error < biggestError {
biggestError = *error;
index = i;
}
}
array[index] -= 1;
}
fn isFinderPattern<const N: usize>(counters: &[u32; N]) -> bool {
if N < 4 {
return false;
}
let firstTwoSum = counters[0] + counters[1];
let sum = firstTwoSum + counters[2] + counters[3];
let ratio: f32 = (firstTwoSum as f32) / (sum as f32);
if ratio >= Self::MIN_FINDER_PATTERN_RATIO && ratio <= Self::MAX_FINDER_PATTERN_RATIO {
let mut minCounter = u32::MAX;
let mut maxCounter = u32::MIN;
for counter in counters {
maxCounter = std::cmp::max(*counter, maxCounter);
minCounter = std::cmp::min(*counter, minCounter);
}
return maxCounter < 10 * minCounter;
}
false
}
}