pub struct Approvers { /* private fields */ }Expand description
The approvers an approval gate requires.
The workflow handler computes them in plain Rust, from its typed input and
the outputs of earlier steps, and passes them to
ApprovalConfig::requiring. The engine
records them on the gate as an ApprovalRequirement when it opens; that
record stays the source of truth on replay and resume.
Deserialization rejects zero approvers and a blank group name.
§Examples
use ironflow_engine::config::Approvers;
let amount = 15_000;
let approvers = match amount {
a if a > 100_000 => Approvers::at_least(3)
.from_groups(["finance", "board"])
.because("amount > 100k"),
a if a > 10_000 => Approvers::at_least(2)
.from_groups(["finance"])
.because("amount > 10k"),
_ => Approvers::any(),
};
assert_eq!(approvers.required(), 2);
assert_eq!(approvers.groups(), ["finance".to_string()]);
assert_eq!(approvers.reason(), Some("amount > 10k"));Implementations§
Source§impl Approvers
impl Approvers
Sourcepub fn any() -> Self
pub fn any() -> Self
One approval, from anyone allowed to answer the gate.
§Examples
use ironflow_engine::config::Approvers;
let approvers = Approvers::any();
assert_eq!(approvers.required(), 1);
assert!(approvers.groups().is_empty());
assert_eq!(approvers.reason(), None);Sourcepub fn from_groups<I, S>(self, groups: I) -> Self
pub fn from_groups<I, S>(self, groups: I) -> Self
Restrict voting to members of the given groups.
Names are trimmed and deduplicated. Admins may always vote.
§Panics
Panics if a group name is empty or only whitespace.
§Examples
use ironflow_engine::config::Approvers;
let approvers = Approvers::at_least(2).from_groups([" finance ", "legal", "finance"]);
assert_eq!(approvers.groups(), ["finance".to_string(), "legal".to_string()]);Sourcepub fn because(self, reason: &str) -> Self
pub fn because(self, reason: &str) -> Self
Record why these approvers are required.
The reason is an audit label shown on the dashboard and carried by the approval events. It is never evaluated.
§Examples
use ironflow_engine::config::Approvers;
let approvers = Approvers::at_least(2).because("amount > 10k");
assert_eq!(approvers.reason(), Some("amount > 10k"));Sourcepub fn required(&self) -> u32
pub fn required(&self) -> u32
Number of distinct approvals the gate needs.
§Examples
use ironflow_engine::config::Approvers;
assert_eq!(Approvers::any().required(), 1);Sourcepub fn groups(&self) -> &[String]
pub fn groups(&self) -> &[String]
Groups whose members may vote. Empty means no group restriction.
§Examples
use ironflow_engine::config::Approvers;
assert!(Approvers::at_least(2).groups().is_empty());Sourcepub fn reason(&self) -> Option<&str>
pub fn reason(&self) -> Option<&str>
Why these approvers are required, if the handler said so.
§Examples
use ironflow_engine::config::Approvers;
assert_eq!(Approvers::any().because("routine").reason(), Some("routine"));Sourcepub fn to_requirement(&self) -> ApprovalRequirement
pub fn to_requirement(&self) -> ApprovalRequirement
The requirement the engine records on the gate.
§Examples
use ironflow_engine::config::{ApprovalRequirement, Approvers};
let requirement = Approvers::at_least(2).from_groups(["finance"]).to_requirement();
assert_eq!(requirement.required_approvers, 2);
assert_eq!(requirement.approver_groups, vec!["finance".to_string()]);
assert_eq!(Approvers::any().to_requirement(), ApprovalRequirement::default());Trait Implementations§
Source§impl<'de> Deserialize<'de> for Approvers
impl<'de> Deserialize<'de> for Approvers
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Approvers
impl StructuralPartialEq for Approvers
Auto Trait Implementations§
impl Freeze for Approvers
impl RefUnwindSafe for Approvers
impl Send for Approvers
impl Sync for Approvers
impl Unpin for Approvers
impl UnsafeUnpin for Approvers
impl UnwindSafe for Approvers
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.