# 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/container-proxy-endpoints/fuse-mount/server/setattr/response/
Specification revision: 2.3.0

```text
[0]             ok
[1][message …]  an error, UTF-8
[2]             read only: the volume behind the mount is read only
```

- **The sequence.** Exactly one channel response, ok, read only, or an error, followed
  by the channel response finish.
- **The message.** The bytes after the error byte are UTF-8, not JSON.
- **Read only.** The byte `2` states that the volume behind the
  mount is read only. The change is refused, and the server reports
  the operation to the program as a read-only filesystem.
- **A finish with nothing.** A channel response finish that no
  channel response precedes states that the client did not serve the
  ask. The server does not ask again.

The channel response is defined by `diverge-sdk-rs/src/shared/containers/fuse/ack/frame.rs`:

```rust
//! Ok, or why not.

use std::convert::Infallible;

use super::super::ResponseError;
use crate::wire::encode::{Encode, Writer};

/// The one message that answers a mutation.
///
/// ```text
/// [kind: u8][message…]
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
    /// Kind `0`. It happened: the caller holds the result.
    Ok,
    /// Kind `1`. It did not, and this says why, for a reader rather
    /// than a program: what a caller can refuse — a mount it keeps
    /// unchangeable, a directory it will not empty, a path it will not
    /// serve — is its policy and not this specification's.
    Error(&'a str),
    /// Kind `2`. It did not, because the volume behind the mount is
    /// read only: its mode is
    /// [`ReadOnly`](crate::provider::endpoints::volumes::Mode::ReadOnly), and
    /// no change is made to it. Nothing after the kind. The program
    /// sees a read-only filesystem, `EROFS`, and every immutable ask
    /// on the same mount goes through.
    ReadOnly,
}

impl Encode for Frame<'_> {
    /// [`Infallible`]: a kind byte and bytes copied.
    type Error = Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Infallible> {
        match self {
            Frame::Ok => out.extend_from_slice(&[0]),
            Frame::Error(message) => {
                out.extend_from_slice(&[1]);
                out.extend_from_slice(message.as_bytes());
            }
            Frame::ReadOnly => out.extend_from_slice(&[2]),
        }
        Ok(())
    }
}

impl<'a> Frame<'a> {
    /// Decode the one message. The message borrows from `bytes`.
    pub fn decode(bytes: &'a [u8]) -> Result<Self, ResponseError> {
        let (kind, rest) = bytes.split_first().ok_or(ResponseError::Empty)?;
        match *kind {
            0 => Ok(Frame::Ok),
            1 => std::str::from_utf8(rest)
                .map(Frame::Error)
                .map_err(|_| ResponseError::MessageUtf8),
            2 => Ok(Frame::ReadOnly),
            other => Err(ResponseError::UnknownKind(other)),
        }
    }
}
```
