# Request

> The payload of the channel request: the tag byte 5 and the request of the channel.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/volumes-fuse-serve/client/mkdir/request/
Specification revision: 2.3.0

```text
[5][path …]
```

- **The form.** The bytes after the tag are exactly the bytes after
  the tag of the [FUSE mkdir](/2.3.0/container-proxy-endpoints/fuse-mount/server/mkdir/request/) ask on a
  mount scope, and mean the same; that page states every field. The
  path is UTF-8, `/`-separated, with no leading `/`; empty is the
  root of the volume.
- **Malformed.** A channel request whose payload does not decode as
  stated is answered by a channel response finish that no channel
  response precedes, and the server does nothing else for it.

The channel request is defined by `diverge-sdk-rs/src/provider/endpoints/volumes/fuse_serve/client/channel_request/frame.rs`:

```rust
//! What a client's channel request frame carries on a FUSE serve scope.

use std::fmt;

use crate::container_proxy::outside::endpoints::fuse::mount::server::channel_request as mount;
use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};

/// What a client asks the provider for while a volume is served: one
/// of the nine asks, the stop, or the tree.
///
/// A payload leads with one byte saying which. The nine asks carry
/// the tags they carry on a mount's scope — `0` read, `1` write, `2`
/// list, `3` remove, `4` rename, `5` mkdir, `6` stat, `7` truncate,
/// `8` setattr — and are that scope's very frames, so a bridge
/// forwards bytes; `9` is the stop, bare; `10` is the tree, bare.
///
/// | tag | asks for |
/// |-----|----------|
/// | `0`–`8` | [`Ask`](Self::Ask): the mount's ask of that tag |
/// | `9` | [`Stop`](Self::Stop) |
/// | `10` | [`Filetree`](Self::Filetree) |
#[derive(Debug, Clone, PartialEq)]
pub enum Frame<'a> {
    /// One of the nine, answered on its channel with that ask's own
    /// frame — the shared vocabulary's — and the finish. The provider
    /// answers as a caller's server would, from the volume.
    Ask(mount::Frame<'a>),
    /// Stop serving. Tag `9`.
    ///
    /// Carries nothing, and nothing comes back on this channel: the
    /// provider sends no channel response and no channel response
    /// finish on it. What comes back is the scope's finish, after
    /// every ask still being answered has been: the provider gives
    /// the volume back and finishes. A second stop changes nothing.
    Stop,
    /// The tree of the volume as this FUSE serve sees it, and then every
    /// change to it. Tag `10`.
    ///
    /// Carries nothing: the scope is the volume, and the root is the
    /// volume's. Answered on its channel with a
    /// [`filetree`](crate::shared::filetree) stream — one snapshot of
    /// the served view, the FUSE serve's layer included, then one frame
    /// per change the FUSE serve's own asks make — for as long as the
    /// scope lives; the channel finishes with the scope. A read-only
    /// volume's stream is its snapshot and nothing after. Any number
    /// of these may be open at once, each a stream of its own
    /// beginning whole.
    Filetree,
}

/// Tag for [`Frame::Stop`].
const STOP: u8 = 9;

/// Tag for [`Frame::Filetree`].
const FILETREE: u8 = 10;

impl Encode for Frame<'_> {
    /// The ask's own failure; the stop and the tree cannot fail.
    type Error = mount::FrameEncodeError;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        match self {
            Frame::Ask(ask) => ask.encode(out),
            Frame::Stop => {
                out.extend_from_slice(&[STOP]);
                Ok(())
            }
            Frame::Filetree => {
                out.extend_from_slice(&[FILETREE]);
                Ok(())
            }
        }
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// The ask's own failures, and the empty payload.
    type Error = FrameError;

    fn decode(bytes: &'a [u8]) -> Result<Self, Self::Error> {
        match bytes.first() {
            None => Err(FrameError::Empty),
            Some(&STOP) => Ok(Frame::Stop),
            Some(&FILETREE) => Ok(Frame::Filetree),
            Some(_) => mount::Frame::decode(bytes).map(Frame::Ask).map_err(FrameError::Ask),
        }
    }
}

/// A FUSE serve channel request that could not be read.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FrameError {
    /// No bytes at all, so not even a tag.
    Empty,
    /// The ask did not decode: an unknown tag, or fewer bytes than it
    /// promises.
    Ask(mount::FrameError),
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Empty => f.write_str("volume FUSE serve channel request frame is empty"),
            FrameError::Ask(error) => write!(f, "volume FUSE serve ask did not decode: {error}"),
        }
    }
}

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

and by `diverge-sdk-rs/src/container_proxy/outside/endpoints/fuse/mount/server/channel_request/path.rs`:

```rust
//! What an ask names when a path is all of it.

use std::str;

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

/// One entry of the mount: its path relative to the mount root —
/// empty for a file mount, and for a directory mount's root.
///
/// ```text
/// [path: utf8…]
/// ```
///
/// The path runs to the end of the payload, so it needs no prefix and
/// takes any length. This is the whole ask for
/// [`List`](super::Frame::List), [`Remove`](super::Frame::Remove),
/// [`Mkdir`](super::Frame::Mkdir) and [`Stat`](super::Frame::Stat),
/// each of which is answered by its own frame. The mount itself is the scope the ask rides.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Path<'a> {
    /// The entry's path inside the mount, `/`-separated, no leading
    /// slash; empty is the mount itself.
    pub path: &'a str,
}

impl Encode for Path<'_> {
    /// [`Infallible`](std::convert::Infallible): the path's bytes are
    /// already bytes.
    type Error = std::convert::Infallible;

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

impl<'a> Path<'a> {
    /// Decode from the bytes after the ask's tag. The path borrows
    /// from `bytes`.
    pub fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        Ok(Path {
            path: str::from_utf8(bytes).map_err(|_| FrameError::PathUtf8)?,
        })
    }
}
```
