Skip to main content

strop_engine/editor/shell/
jobs.rs

1//! Owned shell request identities (R9 §5): every shell job carries a
2//! ticket allocated at registration, and every terminal result —
3//! success, failure, cancellation — owns exactly that ticket. Stale,
4//! duplicated or superseded results die at the handler's registry
5//! check instead of mutating whatever currently occupies the view.
6
7use std::path::PathBuf;
8
9use strop_core::id::{BufferRevision, DocumentId};
10use strop_core::worker::{Ticket, WorkerId};
11
12/// Which surface owns a shell request, captured at registration and
13/// never re-derived from current editor state at delivery.
14#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
15pub enum ShellKey {
16    /// `:!cmd`: an output request for the document that ran it. The
17    /// focus token is the request itself — only the newest display
18    /// request may still switch the view when it lands.
19    Display {
20        origin: DocumentId,
21        revision: BufferRevision,
22        focus: WorkerId,
23    },
24    /// `|cmd`: replace `[start, end)` of a document captured at a
25    /// revision. The range is already normalized, clamped and
26    /// boundary-checked — delivery validates exactly what was
27    /// captured, not re-derived arguments.
28    Pipe {
29        document: DocumentId,
30        revision: BufferRevision,
31        start: usize,
32        end: usize,
33    },
34}
35
36#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
37pub struct ShellIntent {
38    pub ticket: Ticket<ShellKey>,
39    pub command: String,
40    #[serde(with = "strop_core::path_serde")]
41    pub cwd: PathBuf,
42    /// Pipe only: the exact bytes captured for `[start, end)`.
43    pub original: Option<String>,
44}
45
46/// What a shell process produced. Both streams survive failure — a
47/// failed display still shows its output, a failed pipe reports its
48/// stderr — so failures never masquerade as empty successes.
49#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
50pub struct ProcessOutput {
51    pub stdout: String,
52    pub stderr: String,
53}
54
55/// The owned terminal shell result: one per registered request.
56pub type ShellResult = strop_core::worker::Completion<ShellKey, ProcessOutput>;