diff --git a/src/firmware/xbuilder.rs b/src/firmware/xbuilder.rs index c7ce4a6..4bb7b63 100644 --- a/src/firmware/xbuilder.rs +++ b/src/firmware/xbuilder.rs @@ -7,12 +7,15 @@ use chrono::{DateTime, Utc}; use rayon::iter::{ParallelBridge, ParallelIterator}; use tar::Archive; -use crate::recipe_functions::common; +use crate::recipe_functions::common::{self, EnumAsValue}; + +pub type DefaultResult = Result<(), Box>; pub trait Peekable { fn peek(&self) -> Result, Box>; } +#[derive(Debug, Clone)] /// Is expected to get information about last build pub struct LastBuildFirmware { pub path: String, @@ -40,6 +43,13 @@ impl Peekable for LastBuildFirmware { } } +impl LastBuildFirmware { + pub fn update_entries(&mut self) -> DefaultResult { + self.entries = self.peek()?; + Ok(()) + } +} + pub fn read_last_build_firmwares() -> Result, Box> { // get config let ucfg = common::get_config(); @@ -77,3 +87,180 @@ pub fn read_last_build_firmwares() -> Result, Box for CountryShortCode { + fn name(&self) -> String { + format!("{:?}", self.clone()).to_lowercase() + } + + fn value(&self) -> String { + self.name().to_lowercase() + } + + fn get(val: String) -> Self { + return unsafe { std::mem::transmute::<_, CountryShortCode>(val.to_uppercase()) }; + } +} + +#[allow(non_camel_case_types)] +#[derive(Debug, Clone)] +pub enum FirmwareTypes { + FULL, + PATCH, + NOT_FULL, + DEV, + CUSTOM(String), +} + +impl EnumAsValue for FirmwareTypes { + fn name(&self) -> String { + format!("{:?}", self.clone()).to_lowercase() + } + + fn value(&self) -> String { + self.name().to_lowercase() + } + + fn get(val: String) -> Self { + return unsafe { std::mem::transmute::<_, FirmwareTypes>(val.to_uppercase()) }; + } +} + +/// Filter each field in order +pub struct FirmwareFilterOptions { + short_country_code: Option, + version: Option, + fw_type: Option, + additional_condition: Option bool>>, +} + +impl Default for FirmwareFilterOptions { + fn default() -> Self { + Self { + short_country_code: None, + version: None, + fw_type: None, + additional_condition: None, + } + } +} + +impl FirmwareFilterOptions { + pub fn new() -> Self { + FirmwareFilterOptions::default() + } + + pub fn set_cc(&mut self, cc: CountryShortCode) -> &mut Self { + self.short_country_code = Some(cc); + self + } + + pub fn set_version(&mut self, v: String) -> &mut Self { + self.version = Some(v); + self + } + + pub fn set_fw_type(&mut self, fwt: FirmwareTypes) -> &mut Self { + self.fw_type = Some(fwt); + self + } + + pub fn set_more_condition( + &mut self, + cond: Box bool>, + ) -> &mut Self { + self.additional_condition = Some(cond); + self + } +} + +pub struct XBuilder { + saved_firmwares: Vec, +} + +impl XBuilder { + pub fn new() -> Self { + let saved_firmwares = read_last_build_firmwares().unwrap_or(Vec::new()); + + Self { saved_firmwares } + } + + pub fn get_latest_by_options(&self, option: FirmwareFilterOptions) -> Vec { + let mut result = Vec::new(); + + if option.short_country_code.is_some() { + let cc_option = option.short_country_code.unwrap(); + result = self + .saved_firmwares + .iter() + .filter(|fw| fw.path.contains(&cc_option.name())) + .map(|fw| fw.clone()) + .collect(); + } + + if option.version.is_some() { + let filter_target = if result.is_empty() { + self.saved_firmwares.clone() + } else { + result.clone() + }; + let version_option = option.version.unwrap(); + + result = filter_target + .iter() + .filter(|fw| fw.path.contains(&version_option)) + .map(|fw| fw.clone()) + .collect(); + } + + if option.fw_type.is_some() { + let filter_target = if result.is_empty() { + self.saved_firmwares.clone() + } else { + result.clone() + }; + let fw_type = option.fw_type.unwrap(); + + result = filter_target + .iter() + .filter(|fw| fw.path.contains(&fw_type.name())) + .map(|fw| fw.clone()) + .collect(); + } + + if option.additional_condition.is_some() { + let filter_target = if result.is_empty() { + self.saved_firmwares.clone() + } else { + result.clone() + }; + let mut f_result = Vec::new(); + let mut predicate = option.additional_condition.unwrap(); + + for fw in filter_target { + if predicate(fw.clone()) { + f_result.push(fw.clone()); + } + } + + if !f_result.is_empty() { + result = f_result; + } + } + + result + } +} diff --git a/src/recipe_functions/common.rs b/src/recipe_functions/common.rs index dba9f2f..f61d932 100644 --- a/src/recipe_functions/common.rs +++ b/src/recipe_functions/common.rs @@ -5,6 +5,12 @@ use crate::models::{self, recipe::Recipe01}; use std::collections::HashMap; use std::{fs::File, io::Read}; +pub trait EnumAsValue { + fn name(&self) -> String; + fn value(&self) -> T; + fn get(val: T) -> Self; +} + // Change path here! fn extract_tb_config(content: String) -> HashMap {