/vault/get/{channel}
Kind 5: the value under a key, its absence, or an error, in exactly one message.
The ask is kind 5 on /requests:
[5][key …]
The server answers on /vault/get/{channel} by sending exactly one
message and closing the connection. A path that the proxy or the server closes cleanly with no message
before the close states that the ask was not served. An abrupt end of the
path leaves the operation failed, and the proxy does not ask it
again, as Vault provides.
- Three answers. A first byte of
0is followed by the value, which may be empty. A first byte of1states that no value is held under the key. A first byte of2is followed by a message stating why the read failed.
The ask is defined by diverge-provider-sdk/src/shared/containers/vault/get/request/request.rs:
//! Read a key. Answered with the value, or that there is none.
use std::convert::Infallible;
use super::super::super::RequestError;
use crate::encode::{Encode, Writer};
/// Read a key. Answered with the value, or that there is none.
///
/// ```text
/// [key: utf8…]
/// ```
///
/// The key is the whole payload: nothing follows it, so nothing
/// delimits it. Answered with one
/// [`response::Frame`](super::super::response::Frame).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Request<'a> {
/// The key.
pub key: &'a str,
}
impl Encode for Request<'_> {
/// [`Infallible`]: bytes copied.
type Error = Infallible;
fn encode(&self, out: &mut Writer<'_>) -> Result<(), Infallible> {
out.extend_from_slice(self.key.as_bytes());
Ok(())
}
}
impl<'a> Request<'a> {
/// Decode from the bytes after the ask's kind. The key borrows
/// from `bytes`.
pub fn decode(bytes: &'a [u8]) -> Result<Self, RequestError> {
std::str::from_utf8(bytes)
.map(|key| Request { key })
.map_err(|_| RequestError::KeyUtf8)
}
}
The answer is defined by diverge-provider-sdk/src/shared/containers/vault/get/response/frame.rs:
//! The answer to a read.
use std::convert::Infallible;
use super::super::super::ResponseError;
use crate::encode::{Encode, Writer};
/// The one message that answers a read.
///
/// ```text
/// [kind: u8][value… | message…]
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Frame<'a> {
/// Kind `0`. The key's value, verbatim. Empty is a value.
Present(&'a [u8]),
/// Kind `1`. No such key.
Missing,
/// Kind `2`. The read was refused or failed, and this says why —
/// see [`Error`](super::super::super::response::Frame::Error) for
/// why it is a string.
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(value) => {
out.extend_from_slice(&[0]);
out.extend_from_slice(value);
}
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 value or 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::Present(rest)),
1 => Ok(Frame::Missing),
2 => std::str::from_utf8(rest)
.map(Frame::Error)
.map_err(|_| ResponseError::MessageUtf8),
other => Err(ResponseError::UnknownKind(other)),
}
}
}