Skip to main content

uptrakit_surfaces/
slot.rs

1use thiserror::Error;
2
3use crate::{IdentifierError, validate_surface_identifier};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct SurfaceSlotDef {
7    pub id: &'static str,
8    pub multi_entry: bool,
9    pub provider_priority_min: i32,
10    pub provider_priority_max: i32,
11}
12
13impl SurfaceSlotDef {
14    pub const fn single_entry(
15        id: &'static str,
16        provider_priority_min: i32,
17        provider_priority_max: i32,
18    ) -> Self {
19        Self {
20            id,
21            multi_entry: false,
22            provider_priority_min,
23            provider_priority_max,
24        }
25    }
26
27    pub const fn multi_entry(
28        id: &'static str,
29        provider_priority_min: i32,
30        provider_priority_max: i32,
31    ) -> Self {
32        Self {
33            id,
34            multi_entry: true,
35            provider_priority_min,
36            provider_priority_max,
37        }
38    }
39}
40
41pub const SLOT_SETTINGS_TABS: &str = "settings.tabs";
42pub const SLOT_SETTINGS_BELOW_GLOBAL: &str = "settings.below.global";
43pub const SLOT_SOFTWARE_TABS: &str = "software.tabs";
44pub const SLOT_HOST_DETAIL_TABS: &str = "host_detail.tabs";
45pub const SLOT_SOFTWARE_ITEM_TABS: &str = "software_item.tabs";
46pub const SLOT_SOFTWARE_ITEM_HOST_CONTEXT_MENU: &str = "software_item.host_context_menu";
47pub const SLOT_SURFACE_PAGE: &str = "surface.page";
48
49const SURFACE_SLOT_DEFS: [SurfaceSlotDef; 7] = [
50    SurfaceSlotDef::multi_entry(SLOT_SETTINGS_TABS, 100, 999),
51    SurfaceSlotDef::multi_entry(SLOT_SETTINGS_BELOW_GLOBAL, 100, 999),
52    SurfaceSlotDef::multi_entry(SLOT_SOFTWARE_TABS, 100, 999),
53    SurfaceSlotDef::multi_entry(SLOT_HOST_DETAIL_TABS, 100, 999),
54    SurfaceSlotDef::multi_entry(SLOT_SOFTWARE_ITEM_TABS, 100, 999),
55    SurfaceSlotDef::single_entry(SLOT_SOFTWARE_ITEM_HOST_CONTEXT_MENU, 100, 999),
56    SurfaceSlotDef::single_entry(SLOT_SURFACE_PAGE, 100, 999),
57];
58
59pub fn all_surface_slots() -> &'static [SurfaceSlotDef] {
60    &SURFACE_SLOT_DEFS
61}
62
63pub fn slot_def(slot_id: &str) -> Option<&'static SurfaceSlotDef> {
64    SURFACE_SLOT_DEFS.iter().find(|slot| slot.id == slot_id)
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Error)]
68pub enum SlotValidationError {
69    #[error(transparent)]
70    InvalidIdentifier(#[from] IdentifierError),
71    #[error("slot `{0}` is not declared in the slot registry")]
72    UnknownSlot(String),
73}
74
75/// Validates a surface slot identifier and resolves its registered slot definition.
76///
77/// # Errors
78///
79/// Returns [`SlotValidationError::InvalidIdentifier`] if `slot_id` is not a valid
80/// surface identifier, or [`SlotValidationError::UnknownSlot`] if the identifier
81/// is valid but not declared in the slot registry.
82pub fn validate_slot_id(slot_id: &str) -> Result<&'static SurfaceSlotDef, SlotValidationError> {
83    validate_surface_identifier(slot_id)?;
84    slot_def(slot_id).ok_or_else(|| SlotValidationError::UnknownSlot(slot_id.to_owned()))
85}