# 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/daemons-accept/client/connection/response/
Specification revision: 2.3.0

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

- **The sequence.** Zero or more channel responses, each one client
  frame of the daemon protocol with no tag in front, in the order the
  connector sent them on its
  [frames](/2.3.0/endpoints/daemons-connect/server/frames/) channel. The
  channel response finish is the connector hanging up: it follows
  when the connector finishes its frames channel, when the connect
  scope ends, or when the connector's connection ends. A channel
  response finish that no channel response precedes states that the
  id names no connection whose half may be opened, or that the
  connector hung up before sending a frame.
- **The frame.** Each channel response is exactly one client frame of
  the daemon protocol, laid out as [Frames](/2.3.0/frames/) lays out a
  client frame: the type byte, the scope as a `u32` big-endian, the
  channel as a `u32` big-endian, and the payload, running to the end.
  The type is `1`, a request opening a scope; `4`, a channel request
  on a scope; `5`, a channel response on a channel the acceptor
  opened; or `6`, the finish of such a channel. The type `0`, an auth
  frame, never passes: the credential of a daemon connection travels
  in the announcement's `mode`, and the server finishes the frames
  channel of a connector that sends one.
- **The numbers are the connector's.** The scope and the channel in
  a frame are minted by the connector as a client of the acceptor
  mints them, and mean nothing on this wire: nothing between the
  connector and the acceptor reads them.

The channel response is defined by `diverge-sdk-rs/src/provider/endpoints/daemons/accept/server/channel_response/frame.rs`:

```rust
//! What a server's channel response frame carries on the daemon's
//! half of a connection.

/// One client frame the connector sent on the connection, on its way
/// to the daemon. See
/// [`daemon::client::Frame`](crate::shared::containers::daemon::client::Frame):
/// the frame's own bytes, with no tag in front, as the provider
/// forwarded them.
pub type Frame<'a> = crate::shared::containers::daemon::client::Frame<'a>;
```

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

```rust
//! One client 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::client::ClientFrame;

/// One client frame of the daemon protocol, as the program sent it on
/// the proxy's `/daemon`: a request opening a scope, a channel request
/// on one, a channel response or its finish answering a channel the
/// daemon opened on one. One channel response of the caller's half
/// per frame, in the order the program sent them.
///
/// Every variant is the wire's own
/// [`ClientFrame`](crate::wire::frame::client::ClientFrame) variant of
/// the same name, with the same members. The one the wire has and this
/// does not is `Auth`, which never passes: see
/// [`daemon`](crate::shared::containers::daemon).
///
/// # On the wire
///
/// The client frame's own bytes — its type byte, the scope, the
/// channel, the payload — exactly as the wire lays them out, 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> {
    /// Open a scope with a request: a daemon endpoint's request, tag
    /// and all.
    Request {
        /// The scope the program minted.
        scope: u32,
        /// The daemon's request frame, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Open a channel on a scope: a cancel, a stop.
    ChannelRequest {
        /// The scope.
        scope: u32,
        /// The channel the program minted.
        channel: u32,
        /// The channel request, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Answer a channel the daemon opened on a scope: a piece of an
    /// upload's content.
    ChannelResponse {
        /// The scope.
        scope: u32,
        /// The daemon's channel.
        channel: u32,
        /// The channel response, as the endpoint lays it out.
        payload: &'a [u8],
    },
    /// Finish a channel the daemon opened on a scope.
    ChannelResponseFinish {
        /// The scope.
        scope: u32,
        /// The daemon's channel.
        channel: u32,
    },
}

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

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

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

/// The client 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> {
        ClientFrame::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 = ClientFrame::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 client frame of a daemon connection that could not be read.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameError {
    /// Not a client 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 client 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,
        }
    }
}
```
