# Response

> The sequence of channel responses that answers the channel, what ends it, and what a finish with nothing before it means.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/containers-tools-run/server/daemon/response/
Specification revision: 2.3.0

```text
[type: u8][scope: u32][channel: u32][payload …]    zero or more, one server frame each
```

- **The sequence.** Zero or more channel responses, each one server
  frame of the daemon protocol with no tag in front, in the order the
  daemon sent them. The channel response finish is the daemon closing
  the connection: the server closes the program's socket. A channel
  response finish that no channel response precedes states that the
  client declined the connection, and the server closes the program's
  socket at once.
- **The frame.** Each channel response is exactly one server frame of
  the daemon protocol, laid out as [Frames](/2.3.0/frames/) lays out a
  server frame: the type byte `2`, a response; `3`, a response
  finish; `4`, a channel request the daemon opened; `5`, a channel
  response; `6`, a channel response finish; never `0`. The scope and
  the channel in it are the program's, and are not read on this wire.

The channel response is defined by `diverge-sdk-rs/src/provider/endpoints/containers/tools/run/client/channel_response/daemon/frame.rs`:

```rust
//! What a client's response frame carries on a daemon channel.

/// One server frame the daemon sent on the connection, on its way to
/// the program. See
/// [`daemon::server::Frame`](crate::shared::containers::daemon::server::Frame).
///
/// An alias rather than a re-export because this module is real: the
/// path says this scope's answer lives here, and it does, rather than
/// naming somewhere else and hoping a reader follows. What the alias
/// points at is right there in the signature.
pub type Frame<'a> = crate::shared::containers::daemon::server::Frame<'a>;
```

and by `diverge-sdk-rs/src/shared/containers/daemon/server/frame.rs`:

```rust
//! One server frame of the daemon connection, as it crosses a wire.

use std::fmt;

use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};
use crate::wire::frame;
use crate::wire::frame::server::ServerFrame;

/// One server frame of the daemon protocol, as the daemon sends it to
/// the program: a response on a scope, the scope's finish, a channel
/// request the daemon opens on a scope, a channel response or its
/// finish answering a channel the program opened. One channel response
/// of the provider's half per frame, in the order the daemon sent
/// them, and the proxy writes each to the program's socket as it is.
///
/// Every variant is the wire's own
/// [`ServerFrame`](crate::wire::frame::server::ServerFrame) variant of
/// the same name, with the same members; `Auth` is left out, as it is
/// of the [`client::Frame`](crate::shared::containers::daemon::client::Frame).
///
/// # On the wire
///
/// The server frame's own bytes, with no tag in front, so that a
/// bridge forwards bytes. An `Auth` frame, type `0`, does not decode.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
    /// One response on a scope.
    Response {
        /// The scope.
        scope: u32,
        /// The endpoint's response frame.
        payload: &'a [u8],
    },
    /// The scope's finish: no frame follows it on the scope.
    ResponseFinish {
        /// The scope.
        scope: u32,
    },
    /// A channel the daemon opens on a scope: a content ask.
    ChannelRequest {
        /// The scope.
        scope: u32,
        /// The channel the daemon minted.
        channel: u32,
        /// The channel request.
        payload: &'a [u8],
    },
    /// One response on a channel the program opened.
    ChannelResponse {
        /// The scope.
        scope: u32,
        /// The program's channel.
        channel: u32,
        /// The channel response.
        payload: &'a [u8],
    },
    /// The finish of a channel the program opened.
    ChannelResponseFinish {
        /// The scope.
        scope: u32,
        /// The program's channel.
        channel: u32,
    },
}

impl<'a> From<Frame<'a>> for ServerFrame<'a> {
    fn from(frame: Frame<'a>) -> Self {
        match frame {
            Frame::Response { scope, payload } => ServerFrame::Response { scope, payload },
            Frame::ResponseFinish { scope } => ServerFrame::ResponseFinish { scope },
            Frame::ChannelRequest { scope, channel, payload } => ServerFrame::ChannelRequest { scope, channel, payload },
            Frame::ChannelResponse { scope, channel, payload } => ServerFrame::ChannelResponse { scope, channel, payload },
            Frame::ChannelResponseFinish { scope, channel } => ServerFrame::ChannelResponseFinish { scope, channel },
        }
    }
}

impl<'a> TryFrom<ServerFrame<'a>> for Frame<'a> {
    /// The one frame that does not pass.
    type Error = Auth;

    fn try_from(frame: ServerFrame<'a>) -> Result<Self, Auth> {
        Ok(match frame {
            ServerFrame::Auth { .. } => return Err(Auth),
            ServerFrame::Response { scope, payload } => Frame::Response { scope, payload },
            ServerFrame::ResponseFinish { scope } => Frame::ResponseFinish { scope },
            ServerFrame::ChannelRequest { scope, channel, payload } => Frame::ChannelRequest { scope, channel, payload },
            ServerFrame::ChannelResponse { scope, channel, payload } => Frame::ChannelResponse { scope, channel, payload },
            ServerFrame::ChannelResponseFinish { scope, channel } => Frame::ChannelResponseFinish { scope, channel },
        })
    }
}

/// The server frame's own encoding, and nothing in front of it.
impl Encode for Frame<'_> {
    /// [`Infallible`](std::convert::Infallible): a frame is bytes
    /// copied.
    type Error = std::convert::Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        ServerFrame::from(*self).encode(out)
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// The frame that would not decode, or the one that does not pass.
    type Error = FrameError;

    fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        let frame = ServerFrame::decode(bytes).map_err(FrameError::Frame)?;
        Frame::try_from(frame).map_err(|Auth| FrameError::Auth)
    }
}

/// An `Auth` frame where a daemon connection's frame was expected.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Auth;

impl fmt::Display for Auth {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("an auth frame does not pass on a daemon connection")
    }
}

impl std::error::Error for Auth {}

/// A server frame of a daemon connection that could not be read.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameError {
    /// Not a server frame: shorter than its header, or of a type the
    /// wire does not have.
    Frame(frame::FrameError),
    /// An `Auth` frame, which does not pass.
    Auth,
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Frame(error) => write!(f, "daemon connection server frame did not decode: {error}"),
            FrameError::Auth => f.write_str("an auth frame does not pass on a daemon connection"),
        }
    }
}

impl std::error::Error for FrameError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            FrameError::Frame(error) => Some(error),
            FrameError::Auth => None,
        }
    }
}
```
