Skip to main content

lingxia_surface/
presentation.rs

1//! Provider-owned metadata projected into platform surface switchers.
2
3use serde::{Deserialize, Serialize};
4
5use crate::SurfaceContent;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(tag = "source", rename_all = "camelCase")]
9pub enum SurfaceIcon {
10    BuiltIn { name: String },
11    Resource { uri: String },
12    ProviderAsset { provider: String, key: String },
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase")]
17pub struct SurfaceCapabilities {
18    pub close: bool,
19    pub rename: bool,
20}
21
22impl Default for SurfaceCapabilities {
23    fn default() -> Self {
24        Self {
25            close: true,
26            rename: false,
27        }
28    }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct SurfacePresentation {
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    pub automatic_title: Option<String>,
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    pub custom_title: Option<String>,
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub icon: Option<SurfaceIcon>,
40    pub capabilities: SurfaceCapabilities,
41}
42
43impl SurfacePresentation {
44    pub fn for_content(content: &SurfaceContent) -> Self {
45        match content {
46            SurfaceContent::Lxapp { app_id, .. } => Self {
47                automatic_title: Some(app_id.clone()),
48                custom_title: None,
49                icon: Some(SurfaceIcon::ProviderAsset {
50                    provider: "lxapp".into(),
51                    key: app_id.clone(),
52                }),
53                capabilities: SurfaceCapabilities {
54                    close: false,
55                    rename: false,
56                },
57            },
58            SurfaceContent::Page { path, .. } => Self {
59                automatic_title: Some(path.clone()),
60                custom_title: None,
61                icon: None,
62                capabilities: SurfaceCapabilities::default(),
63            },
64            SurfaceContent::Browser { initial_url, .. } => Self {
65                automatic_title: Some(initial_url.clone()),
66                custom_title: None,
67                icon: Some(SurfaceIcon::BuiltIn {
68                    name: "browser".into(),
69                }),
70                capabilities: SurfaceCapabilities::default(),
71            },
72            SurfaceContent::Native { capability, .. } => Self {
73                automatic_title: Some(capability.clone()),
74                custom_title: None,
75                icon: Some(SurfaceIcon::BuiltIn {
76                    name: capability.clone(),
77                }),
78                capabilities: SurfaceCapabilities::default(),
79            },
80        }
81    }
82
83    pub fn title(&self) -> Option<&str> {
84        self.custom_title
85            .as_deref()
86            .or(self.automatic_title.as_deref())
87    }
88
89    pub fn set_custom_title(&mut self, title: Option<&str>) {
90        self.custom_title = title
91            .map(str::trim)
92            .filter(|title| !title.is_empty())
93            .map(str::to_string);
94    }
95}