open_sesame/core/
window.rs1use std::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21pub struct WindowId(String);
22
23impl WindowId {
24 pub fn new(id: impl Into<String>) -> Self {
26 Self(id.into())
27 }
28
29 pub fn as_str(&self) -> &str {
31 &self.0
32 }
33}
34
35impl fmt::Display for WindowId {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "{}", self.0)
38 }
39}
40
41impl From<String> for WindowId {
42 fn from(s: String) -> Self {
43 Self::new(s)
44 }
45}
46
47impl From<&str> for WindowId {
48 fn from(s: &str) -> Self {
49 Self::new(s)
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub struct AppId(String);
72
73impl AppId {
74 pub fn new(id: impl Into<String>) -> Self {
76 Self(id.into())
77 }
78
79 pub fn as_str(&self) -> &str {
81 &self.0
82 }
83
84 pub fn last_segment(&self) -> &str {
88 self.0.split('.').next_back().unwrap_or(&self.0)
89 }
90
91 pub fn to_lowercase(&self) -> String {
93 self.0.to_lowercase()
94 }
95}
96
97impl fmt::Display for AppId {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "{}", self.0)
100 }
101}
102
103impl From<String> for AppId {
104 fn from(s: String) -> Self {
105 Self::new(s)
106 }
107}
108
109impl From<&str> for AppId {
110 fn from(s: &str) -> Self {
111 Self::new(s)
112 }
113}
114
115#[derive(Debug, Clone)]
143pub struct Window {
144 pub id: WindowId,
146 pub app_id: AppId,
148 pub title: String,
150 pub is_focused: bool,
152}
153
154impl Window {
155 pub fn new(
157 id: impl Into<WindowId>,
158 app_id: impl Into<AppId>,
159 title: impl Into<String>,
160 ) -> Self {
161 Self {
162 id: id.into(),
163 app_id: app_id.into(),
164 title: title.into(),
165 is_focused: false,
166 }
167 }
168
169 pub fn with_focus(
171 id: impl Into<WindowId>,
172 app_id: impl Into<AppId>,
173 title: impl Into<String>,
174 is_focused: bool,
175 ) -> Self {
176 Self {
177 id: id.into(),
178 app_id: app_id.into(),
179 title: title.into(),
180 is_focused,
181 }
182 }
183
184 #[cfg(test)]
186 pub fn mock(app_id: &str, title: &str) -> Self {
187 Self::new(format!("mock-{}-{}", app_id, title.len()), app_id, title)
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn test_window_id() {
197 let id = WindowId::new("test-123");
198 assert_eq!(id.as_str(), "test-123");
199 assert_eq!(format!("{}", id), "test-123");
200 }
201
202 #[test]
203 fn test_app_id_last_segment() {
204 let app = AppId::new("com.mitchellh.ghostty");
205 assert_eq!(app.last_segment(), "ghostty");
206
207 let simple = AppId::new("firefox");
208 assert_eq!(simple.last_segment(), "firefox");
209 }
210
211 #[test]
212 fn test_window_creation() {
213 let window = Window::new("id-1", "firefox", "GitHub - Mozilla Firefox");
214 assert_eq!(window.id.as_str(), "id-1");
215 assert_eq!(window.app_id.as_str(), "firefox");
216 assert_eq!(window.title, "GitHub - Mozilla Firefox");
217 }
218}