chanserv: SOP protect (+ao) and founder owner (+qo) with standard ~ & @ prefix tiers
All checks were successful
CI / check (push) Successful in 4m12s
All checks were successful
CI / check (push) Successful in 4m12s
This commit is contained in:
parent
b5aef650f2
commit
e2330c56ff
3 changed files with 31 additions and 28 deletions
|
|
@ -632,7 +632,7 @@ pub const ACCESS_FLAGS: &str = "foOhvtiasg";
|
|||
// The capabilities an access `level` confers (founder is layered on by callers).
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Caps {
|
||||
pub auto: Option<&'static str>, // auto status mode on join: +o / +h / +v
|
||||
pub auto: Option<&'static str>, // auto status mode on join: +qo / +ao / +o / +h / +v
|
||||
pub op: bool, // moderation: kick / ban / op / mode / akick
|
||||
pub topic: bool,
|
||||
pub invite: bool,
|
||||
|
|
@ -647,12 +647,12 @@ pub struct Caps {
|
|||
// entries and new flag entries coexist.
|
||||
pub fn level_caps(level: &str) -> Caps {
|
||||
match level {
|
||||
"founder" => Caps { auto: Some("+o"), op: true, topic: true, invite: true, access: true, set: true, greet: true, rank: 3 },
|
||||
// The XOP tiers, ordered high to low. Every op-and-above tier takes the op
|
||||
// mode (+o), so the whole network keeps a single @ prefix — the tiers are
|
||||
// told apart by capability, not a channel symbol: SOP adds access-list
|
||||
// management (the `access` cap) over AOP, founder adds `set`.
|
||||
"sop" => Caps { auto: Some("+o"), op: true, topic: true, invite: true, access: true, rank: 2, ..Caps::default() },
|
||||
"founder" => Caps { auto: Some("+qo"), op: true, topic: true, invite: true, access: true, set: true, greet: true, rank: 3 },
|
||||
// The XOP tiers, ordered high to low. Each op-and-above tier carries op
|
||||
// (+o, the @ prefix) plus its rank marker: founder owner (+q, ~), sop
|
||||
// protect (+a, &). So AOP and above all show @, while sop outranks aop and
|
||||
// founder outranks sop. SOP additionally holds access-list management.
|
||||
"sop" => Caps { auto: Some("+ao"), op: true, topic: true, invite: true, access: true, rank: 2, ..Caps::default() },
|
||||
"op" => Caps { auto: Some("+o"), op: true, topic: true, invite: true, rank: 2, ..Caps::default() },
|
||||
"halfop" => Caps { auto: Some("+h"), rank: 1, ..Caps::default() },
|
||||
"voice" => Caps { auto: Some("+v"), rank: 1, ..Caps::default() },
|
||||
|
|
@ -1689,23 +1689,26 @@ mod tests {
|
|||
assert!(t.topic && !t.op && t.auto.is_none());
|
||||
assert!(level_caps("a").access && level_caps("f").set);
|
||||
|
||||
// Every op-and-above tier resolves to +o (a single @ prefix). The tiers are
|
||||
// distinguished by capability, not the mode: SOP has `access`, AOP doesn't.
|
||||
// Each op-and-above tier carries op (+o) plus its rank marker, so all show
|
||||
// @: founder +qo (~@), SOP +ao (&@), AOP +o (@), HOP +h.
|
||||
assert!(level_caps("sop").op && level_caps("sop").access);
|
||||
assert_eq!(level_caps("founder").auto, Some("+o"));
|
||||
assert_eq!(level_caps("sop").auto, Some("+o"));
|
||||
assert_eq!(level_caps("founder").auto, Some("+qo"));
|
||||
assert_eq!(level_caps("sop").auto, Some("+ao"), "SOP is op + protect");
|
||||
assert_eq!(level_caps("op").auto, Some("+o"));
|
||||
assert!(level_caps("op").op && !level_caps("op").access);
|
||||
assert_eq!(level_caps("halfop").auto, Some("+h"));
|
||||
|
||||
// Combined, the stronger auto mode wins: op (+o) over a voice group (+v).
|
||||
assert_eq!(level_caps("sop").union(level_caps("voice")).auto, Some("+o"));
|
||||
// Combined, the stronger auto mode wins: SOP (+ao) over a voice group (+v),
|
||||
// and founder (+qo) over everything.
|
||||
assert_eq!(level_caps("sop").union(level_caps("voice")).auto, Some("+ao"));
|
||||
assert_eq!(level_caps("founder").union(level_caps("sop")).auto, Some("+qo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_mode_repeats_the_target_per_letter() {
|
||||
assert_eq!(status_mode("+o", "X"), "+o X");
|
||||
// Multi-letter modes (e.g. the DOWN strip) repeat the target per letter.
|
||||
assert_eq!(status_mode("+ao", "X"), "+ao X X", "protect + op each take the nick");
|
||||
// DOWN strips the whole ladder, so the target repeats once per letter.
|
||||
assert_eq!(status_mode("-qaohv", "X"), "-qaohv X X X X X");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue