Skip to main content

behavior_actors/atomic/
roster.rs

1//! Non-empty immutable worker-role order shared by atomic rosters.
2
3use std::sync::Arc;
4
5pub(crate) struct RoleName<Role> {
6    role: Arc<Role>,
7}
8
9impl<Role> RoleName<Role> {
10    pub(crate) fn new(role: Role) -> Self {
11        Self {
12            role: Arc::new(role),
13        }
14    }
15
16    pub(crate) fn into_role(self) -> Arc<Role> {
17        self.role
18    }
19
20    pub(crate) fn role(&self) -> &Role {
21        self.role.as_ref()
22    }
23}
24
25impl<Role> Clone for RoleName<Role> {
26    fn clone(&self) -> Self {
27        Self {
28            role: Arc::clone(&self.role),
29        }
30    }
31}
32
33/// A non-empty sequence of distinct application roles in semantic order.
34#[derive(Debug, Eq, PartialEq)]
35pub struct OrderedRoles<Role> {
36    declared: Vec<Role>,
37}
38
39/// A repeated role and every role value retained by failed roster validation.
40#[derive(Debug, Eq, PartialEq)]
41pub struct DuplicateRole<Role> {
42    /// Roles accepted before the repetition.
43    pub declared: Vec<Role>,
44    /// The repeated role.
45    pub duplicate: Role,
46    /// Roles not examined after the repetition.
47    pub remaining: Vec<Role>,
48}
49
50impl<Role> OrderedRoles<Role>
51where
52    Role: Eq,
53{
54    /// Validate one required first role followed by any number of later roles.
55    pub fn new(
56        first: Role,
57        remaining: impl IntoIterator<Item = Role>,
58    ) -> Result<Self, DuplicateRole<Role>> {
59        let mut declared = vec![first];
60        let mut remaining = remaining.into_iter();
61        loop {
62            let role = match remaining.next() {
63                Some(role) => role,
64                None => return Ok(Self { declared }),
65            };
66            match declared.iter().position(|candidate| candidate == &role) {
67                Some(_) => {
68                    return Err(DuplicateRole {
69                        declared,
70                        duplicate: role,
71                        remaining: remaining.collect(),
72                    });
73                }
74                None => declared.push(role),
75            }
76        }
77    }
78}
79
80impl<Role> OrderedRoles<Role> {
81    pub(crate) fn into_roles(self) -> Vec<Role> {
82        self.declared
83    }
84}