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.
- The sequence. Exactly one channel response, in the form the Container Proxy Endpoints layer defines, followed by the channel response finish.
- A finish with nothing. A channel response finish that no channel response precedes states that the client did not serve the ask. The server relays that to the proxy as a channel response finish that no channel response precedes, and does not ask again.
The channel response is defined by diverge-sdk-rs/src/shared/containers/fuse/read/response/frame.rs:
//! The answer to a read.
use std::convert::Infallible;
use super::super::super::ResponseError;
use crate::wire::encode::{Encode, Writer};
/// The one message that answers a read.
///
/// ```text
/// [kind: u8][bytes… | message…]
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
/// Kind `0`. The piece's bytes, verbatim: at most the length
/// asked, fewer at the end of the file, and none at or past it.
Present(&'a [u8]),
/// Kind `1`. The caller holds nothing at the path: on a file
/// mount, nothing under the id yet, and the file reads as empty
/// until the first write makes it.
Missing,
/// Kind `2`. The read was refused or failed, and this says why,
/// for a reader rather than a program: what a caller can refuse
/// is its policy and not this specification's.
Error(&'a str),
}
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::Present(bytes) => {
out.extend_from_slice(&[0]);
out.extend_from_slice(bytes);
}
Frame::Missing => out.extend_from_slice(&[1]),
Frame::Error(message) => {
out.extend_from_slice(&[2]);
out.extend_from_slice(message.as_bytes());
}
}
Ok(())
}
}
impl<'a> Frame<'a> {
/// Decode the one message. The bytes or message borrow 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::Present(rest)),
1 => Ok(Frame::Missing),
2 => std::str::from_utf8(rest)
.map(Frame::Error)
.map_err(|_| ResponseError::MessageUtf8),
other => Err(ResponseError::UnknownKind(other)),
}
}
}