Skip to content

Commit

Permalink
[no ci] wip
Browse files Browse the repository at this point in the history
  • Loading branch information
CyonAlexRDX committed Nov 25, 2024
1 parent b29bb93 commit 6d7c038
Showing 1 changed file with 118 additions and 30 deletions.
148 changes: 118 additions & 30 deletions crates/rules/src/roles_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ impl RoleBuilder {

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RoleBuilderValidation {
/// e.g. tried to remove a factor source which was not found.
FactorSourceNotFound,
ForeverInvalid(ForeverInvalidReason),
NotYetValid(NotYetValidReason),
}
Expand Down Expand Up @@ -147,6 +149,38 @@ pub trait BuilderOfFactorsInRole: Sized + private::UncheckedBuilderOfFactorsInRo
self.validate()
}

fn override_contains_factor_source(&self, factor_source: &FactorSource) -> bool {
self.override_factors().contains(&factor_source)
}

fn threshold_contains_factor_source(&self, factor_source: &FactorSource) -> bool {
self.threshold_factors().contains(&factor_source)
}

/// # Throws
/// Throws an error if the specified `factor_source` was not in any of the two lists.
fn remove_factor_source(&mut self, factor_source: &FactorSource) -> RoleBuilderMutateResult;

fn override_contains_factor_source_of_kind(
&self,
factor_source_kind: FactorSourceKind,
) -> bool {
self.override_factors()
.into_iter()
.find(|f| f.factor_source_kind() == factor_source_kind)
.is_some()
}

fn threshold_contains_factor_source_of_kind(
&self,
factor_source_kind: FactorSourceKind,
) -> bool {
self.threshold_factors()
.into_iter()
.find(|f| f.factor_source_kind() == factor_source_kind)
.is_some()
}

/// If Ok => self is mutated
/// If Err(NotYetValid) => self is mutated
/// If Err(ForeverInvalid) => self is not mutated
Expand All @@ -161,7 +195,8 @@ pub trait BuilderOfFactorsInRole: Sized + private::UncheckedBuilderOfFactorsInRo
Ok(()) | Err(RoleBuilderValidation::NotYetValid(_)) => {
self.unchecked_add_factor_source_to_list(factor_source, factor_list_kind);
}
Err(RoleBuilderValidation::ForeverInvalid(_)) => {}
Err(RoleBuilderValidation::ForeverInvalid(_))
| Err(RoleBuilderValidation::FactorSourceNotFound) => {}
}
validation
}
Expand Down Expand Up @@ -328,6 +363,33 @@ impl BuilderOfFactorsInRole for RoleBuilder {
|| self.threshold_contains_factor_source_of_kind(factor_source_kind)
}

/// Lowers the threshold if the deleted factor source is in the threshold list
/// and if after removal of `factor_source` `self.threshold > self.threshold_factors.len()`
fn remove_factor_source(&mut self, factor_source: &FactorSource) -> RoleBuilderMutateResult {
if !self.contains_factor_source(factor_source) {
return RoleBuilderMutateResult::Err(RoleBuilderValidation::FactorSourceNotFound);
}
let remove = |xs: &mut Vec<FactorSource>| {
let index = xs
.iter()
.position(|f| f == factor_source)
.expect("Called remove of non existing FactorSource, this is a programmer error, should have checked if it exists before calling remove.");
xs.remove(index);
};

if self.override_contains_factor_source(factor_source) {
remove(&mut self.override_factors)
}
if self.threshold_contains_factor_source(factor_source) {
remove(&mut self.threshold_factors);
let threshold_factors_len = self.threshold_factors.len() as u8;
if self.threshold > threshold_factors_len {
self.set_threshold(threshold_factors_len)?;
}
}
Ok(())
}

fn validation_for_addition_of_factor_source_of_kind_to_list_for_primary(
&self,
factor_source_kind: FactorSourceKind,
Expand Down Expand Up @@ -482,34 +544,6 @@ impl RoleBuilder {
}

impl RoleBuilder {
fn override_contains_factor_source(&self, factor_source: &FactorSource) -> bool {
self.override_factors.contains(factor_source)
}

fn threshold_contains_factor_source(&self, factor_source: &FactorSource) -> bool {
self.threshold_factors.contains(factor_source)
}

fn override_contains_factor_source_of_kind(
&self,
factor_source_kind: FactorSourceKind,
) -> bool {
self.override_factors
.iter()
.find(|f| f.factor_source_kind() == factor_source_kind)
.is_some()
}

fn threshold_contains_factor_source_of_kind(
&self,
factor_source_kind: FactorSourceKind,
) -> bool {
self.threshold_factors
.iter()
.find(|f| f.factor_source_kind() == factor_source_kind)
.is_some()
}

fn factor_sources_not_of_kind_to_list_of_kind(
&self,
factor_source_kind: FactorSourceKind,
Expand Down Expand Up @@ -1401,7 +1435,7 @@ mod tests {
}

#[cfg(test)]
mod set_threshold_suite {
mod threshold_suite {
use super::*;

fn sample() -> FactorSource {
Expand All @@ -1420,6 +1454,60 @@ mod tests {
FactorListKind::Threshold
}

#[test]
fn remove_lowers_threshold_from_1_to_0() {
let mut sut = make();
let fs = sample();
sut.add_factor_source_to_list(fs.clone(), list()).unwrap();
sut.set_threshold(1).unwrap();
assert_eq!(sut.threshold, 1);
sut.remove_factor_source(&fs).unwrap();
assert_eq!(sut.threshold, 0);
}

#[test]
fn remove_lowers_threshold_from_3_to_1() {
let mut sut = make();
let fs0 = sample();
let fs1 = sample_other();
sut.add_factor_source_to_list(fs0.clone(), list()).unwrap();
sut.add_factor_source_to_list(fs1.clone(), list()).unwrap();
sut.add_factor_source_to_list(FactorSource::sample_arculus_other(), list())
.unwrap();
sut.set_threshold(3).unwrap();
assert_eq!(sut.threshold, 3);
sut.remove_factor_source(&fs0).unwrap();
sut.remove_factor_source(&fs1).unwrap();
assert_eq!(sut.threshold, 1);
}

#[test]
fn remove_from_override_does_not_change_threshold() {
let mut sut = make();
sut.add_factor_source_to_list(sample(), list()).unwrap();
sut.add_factor_source_to_list(sample_other(), list())
.unwrap();
let fs = FactorSource::sample_arculus_other();
sut.add_factor_source_to_list(fs.clone(), FactorListKind::Override)
.unwrap();
sut.set_threshold(2).unwrap();
assert_eq!(sut.threshold, 2);
sut.remove_factor_source(&fs).unwrap();
assert_eq!(sut.threshold, 2);

let built = sut.build().unwrap();
assert_eq!(
built,
RoleWithFactors {
built: PhantomData,
role: role(),
threshold: 2,
threshold_factors: vec![sample(), sample_other()],
override_factors: Vec::new(),
}
);
}

#[test]
fn one_factor_then_set_threshold_to_one_is_ok() {
// Arrange
Expand Down

0 comments on commit 6d7c038

Please sign in to comment.