# Response

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

Canonical: https://provider.diverge.network/2.3.0/endpoints/containers-agents-run/server/write-bytes/response/
Specification revision: 2.3.0

```text
[0][bytes …]         zero or more, the content
[1][error JSON …]    last, the content was not streamed whole
```

- **The sequence.** Zero or more channel responses whose first byte
  is `0`, each a piece of the content, in order; the pieces
  concatenated are the file. An error, when the client sends one, is
  the last channel response, and the write does not happen. The
  channel response finish ends the content. A channel response
  finish that no channel response precedes is a file of zero bytes.
- **The error.** After the byte `1`, exactly one JSON value in the form defined on the [volumes::list response](/2.3.0/endpoints/volumes-list/response/) page. The server
  relays it as the error of the client's write channel.

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

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

use std::fmt;

use crate::decode::Decode;
use crate::encode::{Encode, Writer};
use crate::shared::containers::write_bytes;
use crate::shared::error::Error;

/// A piece of the file being written, or the news that there will not
/// be one.
///
/// A payload leads with one byte saying which — `0` for
/// [`Body`](Self::Body), `1` for [`Error`](Self::Error) — and the rest
/// is that variant's own bytes.
///
/// # How it ends
///
/// | the channel ends with | means |
/// |-----------------------|-------|
/// | bodies, then a finish | that was the whole content |
/// | an [`Error`](Self::Error), then a finish | the full content was not streamed |
///
/// Only a finish ends it. What a provider does with a write that
/// ended in an error is not specified here.
///
/// # The failure is this scope's, the bytes are not
///
/// [`Body`](Self::Body) carries
/// [`write_bytes::response::Frame`](crate::shared::containers::write_bytes::response::Frame),
/// which is what a piece of a file is anywhere. The
/// [`Error`](Self::Error) beside it is the exchange's own.
#[derive(Debug, Clone, PartialEq)]
pub enum Frame<'a> {
    /// A piece of the file. Tag `0`.
    Body(write_bytes::response::Frame<'a>),
    /// A failure. Tag `1`.
    ///
    /// The caller cannot supply the content it was asked for — the
    /// source went away, the read it was piping stopped, whatever it
    /// knows. See [`shared::error::Error`](crate::shared::error::Error)
    /// for why it says so little.
    Error(Error),
}

/// Tag for [`Frame::Body`].
const BODY: u8 = 0;

/// Tag for [`Frame::Error`].
const ERROR: u8 = 1;

impl Encode for Frame<'_> {
    /// The ordinary JSON failure, from the half that has one. Copying
    /// a slice into a buffer cannot fail.
    type Error = serde_json::Error;

    // Spelled out rather than `Self::Error`: this enum has a variant
    // called `Error`, so the associated type is ambiguous by that name.
    fn encode(
        &self,
        out: &mut Writer<'_>,
    ) -> Result<(), serde_json::Error> {
        match self {
            Frame::Body(body) => {
                out.extend_from_slice(&[BODY]);
                // Its error is `Infallible`, and an empty match on one
                // is how you say so: there is no value to handle.
                body.encode(out).map_err(|error| match error {})
            }
            Frame::Error(error) => {
                out.extend_from_slice(&[ERROR]);
                error.encode(out)
            }
        }
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// Three ways to fail, and only one of them is a parse.
    type Error = FrameError;

    // Spelled out for the same reason as `encode` above.
    fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        let (tag, rest) = bytes.split_first().ok_or(FrameError::Empty)?;
        match *tag {
            BODY => write_bytes::response::Frame::decode(rest)
                .map(Frame::Body)
                .map_err(|error| match error {}),
            ERROR => {
                Error::decode(rest).map(Frame::Error).map_err(FrameError::Error)
            }
            tag => Err(FrameError::UnknownTag(tag)),
        }
    }
}

/// A write content frame that could not be read.
#[derive(Debug)]
pub enum FrameError {
    /// No bytes at all, so not even a tag.
    ///
    /// Distinct from a zero-length body, which is a tag followed by
    /// nothing and is ordinary on a stream.
    Empty,
    /// A tag that is neither of this frame's two.
    UnknownTag(u8),
    /// The error did not parse.
    Error(serde_json::Error),
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Empty => f.write_str("write content frame is empty"),
            FrameError::UnknownTag(tag) => {
                write!(f, "unknown write content frame tag {tag}")
            }
            FrameError::Error(error) => {
                write!(f, "write content error did not parse: {error}")
            }
        }
    }
}

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

and by `diverge-provider-sdk/src/shared/containers/write_bytes/response/frame.rs`:

```rust
//! A write's content, arriving.

use std::convert::Infallible;

use crate::decode::Decode;
use crate::encode::{Encode, Writer};

/// A piece of the file being written.
///
/// Bytes and nothing else — no tag, because there is nothing here to
/// discriminate. This is the CONTENT, and content is the same content
/// wherever a write happens.
///
/// # Failing is not this type's business
///
/// Whether a channel carrying this can also carry a failure is the
/// endpoint's to decide, and the endpoints that allow one wrap this in
/// an enum of their own — every
/// [`containers`](crate::endpoints::containers) scope does.
///
/// Putting the failure here would mean one vocabulary of errors for
/// every endpoint that ever streams a write, decided by whichever
/// needed one first. What can go wrong is endpoint logic; what a piece
/// of a file looks like is not.
///
/// # How it ends
///
/// With a finish, and only with a finish. There is no terminator in
/// the payload because the frame layer already has one, and a second
/// would be two signals for one fact.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Frame<'a>(
    /// The bytes, borrowed from the frame they arrived in.
    pub &'a [u8],
);

impl Encode for Frame<'_> {
    /// [`Infallible`]: copying a slice into a buffer has no failure
    /// mode.
    type Error = Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        out.extend_from_slice(self.0);
        Ok(())
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// [`Infallible`]: there is nothing to get wrong about a slice
    /// that is already the answer.
    type Error = Infallible;

    fn decode(bytes: &'a [u8]) -> Result<Self, Self::Error> {
        Ok(Frame(bytes))
    }
}
```
