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}