shep-channel 0.15.2

Client for the shep shepherd channel: readiness, metrics and custom actions over the descriptor shep hands a supervised process
Documentation
/// Anything that can go wrong on the shepherd channel.
///
/// `#[non_exhaustive]` per IR-20: this is on the peer-facing surface, which
/// will grow reasons to fail.
#[non_exhaustive]
#[derive(Debug)]
pub enum ChannelError {
    /// The transport failed. Carries the underlying error.
    Io(std::io::Error),
    /// One frame could not be encoded or decoded. Carries serde's message.
    ///
    /// Recoverable: the frame is lost, and the next call resumes at the
    /// next line. The daemon does the same with a bad frame going the
    /// other way.
    Malformed(String),
    /// The environment names a channel this platform cannot open, for
    /// example `SHEP_CHANNEL_PIPE` on unix. Carries the variable and value.
    Unusable(String),
    /// The writer has stopped, so the message never reached the
    /// shepherd: it was refused at the queue, or it was queued and the
    /// writer returned before writing it.
    Closed,
    /// A [`crate::Shepherd::flush`] ran out of time with messages still
    /// waiting for the writer. They may yet be written.
    TimedOut,
    /// This process already took its shepherd channel. A second
    /// [`crate::Channel::open`] call returns this rather than retake the
    /// descriptor, which would produce two owners.
    AlreadyTaken,
}

impl core::fmt::Display for ChannelError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Io(error) => write!(f, "shepherd channel I/O failed: {error}"),
            Self::Malformed(message) => write!(f, "malformed shepherd-channel frame: {message}"),
            Self::Unusable(what) => write!(f, "unusable shepherd channel: {what}"),
            Self::Closed => f.write_str("the shepherd channel is closed"),
            Self::TimedOut => f.write_str("the shepherd channel did not finish writing in time"),
            Self::AlreadyTaken => f.write_str(
                "the shepherd channel has already been taken by this process and can only be taken once",
            ),
        }
    }
}

impl core::error::Error for ChannelError {
    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
        match self {
            Self::Io(error) => Some(error),
            _ => None,
        }
    }
}