use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(u8)]
pub enum WireVersion {
V1 = 1,
V2 = 2,
}
impl WireVersion {
pub const fn as_u8(self) -> u8 {
self as u8
}
pub const fn from_u8(v: u8) -> Option<Self> {
match v {
1 => Some(Self::V1),
2 => Some(Self::V2),
_ => None,
}
}
pub const fn as_str(self) -> &'static str {
match self {
Self::V1 => "v1",
Self::V2 => "v2",
}
}
}
impl fmt::Display for WireVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum HookKind {
Filter,
Shape,
Observe,
TransformResponse,
TransformSseEvent,
}
impl HookKind {
pub const fn as_str(self) -> &'static str {
match self {
Self::Filter => "filter",
Self::Shape => "shape",
Self::Observe => "observe",
Self::TransformResponse => "transform_response",
Self::TransformSseEvent => "transform_sse_event",
}
}
pub const fn export_name(self) -> &'static str {
match self {
Self::Filter => "cc_lb_filter",
Self::Shape => "cc_lb_shape",
Self::Observe => "cc_lb_observe",
Self::TransformResponse => "cc_lb_transform_response",
Self::TransformSseEvent => "cc_lb_transform_sse_event",
}
}
pub const fn section_prefix(self) -> &'static str {
match self {
Self::Filter => "cc_lb.schema.filter",
Self::Shape => "cc_lb.schema.shape",
Self::Observe => "cc_lb.schema.observe",
Self::TransformResponse => "cc_lb.schema.transform_response",
Self::TransformSseEvent => "cc_lb.schema.transform_sse_event",
}
}
pub const ALL: &'static [HookKind] = &[
Self::Filter,
Self::Shape,
Self::Observe,
Self::TransformResponse,
Self::TransformSseEvent,
];
pub fn parse(s: &str) -> Option<Self> {
match s {
"filter" => Some(Self::Filter),
"shape" => Some(Self::Shape),
"observe" => Some(Self::Observe),
"transform_response" => Some(Self::TransformResponse),
"transform_sse_event" => Some(Self::TransformSseEvent),
_ => None,
}
}
}
impl fmt::Display for HookKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub const HOST_SUPPORTED_FILTER_VERSIONS: &[WireVersion] = &[WireVersion::V1, WireVersion::V2];
pub const HOST_SUPPORTED_SHAPE_VERSIONS: &[WireVersion] = &[WireVersion::V1];
pub const HOST_SUPPORTED_OBSERVE_VERSIONS: &[WireVersion] = &[WireVersion::V1];
pub const HOST_SUPPORTED_TRANSFORM_RESPONSE_VERSIONS: &[WireVersion] = &[WireVersion::V1];
pub const HOST_SUPPORTED_TRANSFORM_SSE_EVENT_VERSIONS: &[WireVersion] = &[WireVersion::V1];
pub fn host_supported_versions(hook: HookKind) -> &'static [WireVersion] {
match hook {
HookKind::Filter => HOST_SUPPORTED_FILTER_VERSIONS,
HookKind::Shape => HOST_SUPPORTED_SHAPE_VERSIONS,
HookKind::Observe => HOST_SUPPORTED_OBSERVE_VERSIONS,
HookKind::TransformResponse => HOST_SUPPORTED_TRANSFORM_RESPONSE_VERSIONS,
HookKind::TransformSseEvent => HOST_SUPPORTED_TRANSFORM_SSE_EVENT_VERSIONS,
}
}
pub fn host_supports(hook: HookKind, version: WireVersion) -> bool {
host_supported_versions(hook).contains(&version)
}
pub trait WireSchema {
const FINGERPRINT: [u8; 32];
const DESCRIPTOR: &'static str;
}
pub const fn pack_ret(ptr: u32, len: u32) -> u64 {
((ptr as u64) << 32) | (len as u64)
}
pub const fn unpack_ret(packed: u64) -> (u32, u32) {
let ptr = (packed >> 32) as u32;
let len = (packed & 0xFFFF_FFFF) as u32;
(ptr, len)
}