Skip to main content

strop_workspace/
filesystem.rs

1//! The filesystem namespace a path names: the local disk, or exactly one
2//! remote endpoint. Part of identity — two filesystems never share a path,
3//! so a remote path can never alias a local path with the same bytes.
4//!
5//! This supersedes strop-lsp's `FsTarget` (0042): one definition for the
6//! editor, LSP, Git and the picker instead of one per consumer. The serde
7//! wire shape is unchanged (`Local` / `Remote`), so traces and sessions
8//! written before the move still decode.
9use crate::addr::RemoteEndpoint;
10use crate::container::ContainerId;
11
12/// The filesystem a path names.
13#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
14pub enum Filesystem {
15    Local,
16    Remote(RemoteEndpoint),
17    /// A running container on the local engine (0037 DC1a) — paths inside
18    /// it are never local paths.
19    Container(ContainerId),
20}
21
22impl Default for Filesystem {
23    /// The local disk: records predating remote filesystems deserialize
24    /// as local — never guessed remote.
25    fn default() -> Self {
26        Self::Local
27    }
28}
29
30impl Filesystem {
31    /// Modeline/trace form: bare for local, the endpoint URI otherwise.
32    /// Modeline/trace form: bare for local, the endpoint URI or the
33    /// short container id otherwise.
34    pub fn label(&self) -> String {
35        match self {
36            Self::Local => "local".to_string(),
37            Self::Remote(endpoint) => endpoint.to_string(),
38            Self::Container(id) => format!("container:{}", &id.as_str()[..12]),
39        }
40    }
41
42    pub fn is_remote(&self) -> bool {
43        matches!(self, Self::Remote(_))
44    }
45
46    pub fn endpoint(&self) -> Option<&RemoteEndpoint> {
47        match self {
48            Self::Remote(endpoint) => Some(endpoint),
49            _ => None,
50        }
51    }
52}