tab_api/
tab.rs

1//! Common metadata about Tabs.
2
3use lifeline::impl_storage_clone;
4use serde::{Deserialize, Serialize};
5use std::{collections::HashMap, fmt::Display, num::ParseIntError, str::FromStr};
6
7pub fn normalize_name(name: &str) -> String {
8    let name = name.to_string().trim().to_string();
9    if name.ends_with("/") {
10        name
11    } else {
12        name + "/"
13    }
14}
15
16pub fn validate_tab_name(name: String) -> Result<(), String> {
17    if name.starts_with('-') {
18        return Err("tab name may not begin with a dash".into());
19    }
20
21    if name.contains(' ') || name.contains('\t') || name.contains('\r') || name.contains('\n') {
22        return Err("tab name may not contain whitespace".into());
23    }
24
25    if name.contains('\\') {
26        return Err("tab name may not contain backslashes".into());
27    }
28
29    Ok(())
30}
31
32/// Identifies a running tab using a numeric index.
33#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, PartialEq, Eq)]
34pub struct TabId(pub u16);
35impl_storage_clone!(TabId);
36
37impl FromStr for TabId {
38    type Err = ParseIntError;
39
40    fn from_str(s: &str) -> Result<Self, Self::Err> {
41        let id = u16::from_str(s)?;
42        Ok(Self(id))
43    }
44}
45
46impl Display for TabId {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        f.write_str("TabId(")?;
49        self.0.fmt(f)?;
50        f.write_str(")")?;
51
52        Ok(())
53    }
54}
55
56/// Tracked information about a running tab.
57#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
58pub struct TabMetadata {
59    pub id: TabId,
60    pub name: String,
61    pub doc: Option<String>,
62    pub dimensions: (u16, u16),
63    pub env: HashMap<String, String>,
64    pub shell: String,
65    pub dir: String,
66}
67
68impl TabMetadata {
69    pub fn create(id: TabId, create: CreateTabMetadata) -> Self {
70        Self {
71            id,
72            name: create.name,
73            doc: create.doc,
74            dimensions: create.dimensions,
75            env: create.env,
76            shell: create.shell,
77            dir: create.dir,
78        }
79    }
80}
81
82/// Information about a tab which will be created.
83#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
84pub struct CreateTabMetadata {
85    pub name: String,
86    pub dimensions: (u16, u16),
87    pub doc: Option<String>,
88    pub env: HashMap<String, String>,
89    pub shell: String,
90    pub dir: String,
91}