gix_filter/driver/process/
mod.rs

1use std::collections::HashSet;
2
3/// A set of capabilities that have been negotiated between client and server.
4pub type Capabilities = HashSet<String>;
5
6/// A handle to a client that allows communicating to a long-running process.
7pub struct Client {
8    /// The child process we are communicating with.
9    child: std::process::Child,
10    /// The names of the obtained capabilities after the handshake.
11    capabilities: Capabilities,
12    /// The negotiated version of the protocol.
13    version: usize,
14    /// A way to send packet-line encoded information to the process.
15    input: gix_packetline_blocking::Writer<std::process::ChildStdin>,
16    /// A way to read information sent to us by the process.
17    out: gix_packetline_blocking::StreamingPeekableIter<std::process::ChildStdout>,
18}
19
20/// A handle to facilitate typical server interactions that include the handshake and command-invocations.
21pub struct Server {
22    /// The names of the capabilities we can expect the client to use.
23    capabilities: Capabilities,
24    /// The negotiated version of the protocol, it's the highest supported one.
25    version: usize,
26    /// A way to receive information from the client.
27    input: gix_packetline_blocking::StreamingPeekableIter<std::io::StdinLock<'static>>,
28    /// A way to send information to the client.
29    out: gix_packetline_blocking::Writer<std::io::StdoutLock<'static>>,
30}
31
32/// The return status of an [invoked command][Client::invoke()].
33#[derive(Debug, Clone)]
34pub enum Status {
35    /// No new status was set, and nothing was sent, so instead we are to assume the previous status is still in effect.
36    Previous,
37    /// Something was sent, but we couldn't identify it as status.
38    Unset,
39    /// Assume the given named status.
40    Named(String),
41}
42
43/// Initialization
44impl Status {
45    /// Create a new instance that represents a successful operation.
46    pub fn success() -> Self {
47        Status::Named("success".into())
48    }
49
50    /// Create a new instance that represents a delayed operation.
51    pub fn delayed() -> Self {
52        Status::Named("delayed".into())
53    }
54
55    /// Create a status that indicates to the client that the command that caused it will not be run anymore throughout the lifetime
56    /// of the process. However, other commands may still run.
57    pub fn abort() -> Self {
58        Status::Named("abort".into())
59    }
60
61    /// Create a status that makes the client send a kill signal.
62    pub fn exit() -> Self {
63        Status::Named("send-term-signal".into())
64    }
65
66    /// Create a new instance that represents an error with the given `message`.
67    pub fn error(message: impl Into<String>) -> Self {
68        Status::Named(message.into())
69    }
70}
71
72/// Access
73impl Status {
74    /// Note that this is assumed true even if no new status is set, hence we assume that upon error, the caller will not continue
75    /// interacting with the process.
76    pub fn is_success(&self) -> bool {
77        match self {
78            Status::Previous => true,
79            Status::Unset => false,
80            Status::Named(n) => n == "success",
81        }
82    }
83
84    /// Returns true if this is an `abort` status.
85    pub fn is_abort(&self) -> bool {
86        self.message() == Some("abort")
87    }
88
89    /// Return true if the status is explicitly set to indicated delayed output processing
90    pub fn is_delayed(&self) -> bool {
91        match self {
92            Status::Previous | Status::Unset => false,
93            Status::Named(n) => n == "delayed",
94        }
95    }
96
97    /// Return the status message if present.
98    pub fn message(&self) -> Option<&str> {
99        match self {
100            Status::Previous | Status::Unset => None,
101            Status::Named(msg) => msg.as_str().into(),
102        }
103    }
104}
105
106///
107pub mod client;
108
109///
110pub mod server;
111
112type PacketlineReader<'a, T = std::process::ChildStdout> = gix_packetline_blocking::read::WithSidebands<
113    'a,
114    T,
115    fn(bool, &[u8]) -> gix_packetline_blocking::read::ProgressAction,
116>;