#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum NarrowPolicy {
Combined,
#[default]
AutoOnModeset,
PerCrtc,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub struct SlotState {
pub is_hole: bool,
pub wants_modeset: bool,
}
#[must_use]
pub fn partition_for_policy(slots: &[SlotState], policy: NarrowPolicy) -> Vec<Vec<usize>> {
let engaged = || {
slots
.iter()
.enumerate()
.filter(|(_, slot)| !slot.is_hole)
.map(|(index, _)| index)
};
match policy {
NarrowPolicy::PerCrtc => engaged().map(|index| vec![index]).collect(),
NarrowPolicy::Combined => {
let combined: Vec<usize> = engaged().collect();
if combined.is_empty() {
Vec::new()
} else {
vec![combined]
}
}
NarrowPolicy::AutoOnModeset => {
let (modeset, steady): (Vec<usize>, Vec<usize>) =
engaged().partition(|index| slots[*index].wants_modeset);
match (modeset.is_empty(), steady.is_empty()) {
(true, true) => Vec::new(),
(false, false) => vec![modeset, steady],
(false, true) => vec![modeset],
(true, false) => vec![steady],
}
}
}
}