pub(crate) use as_header_name::AsHeaderName;
pub(crate) use as_header_value::AsHeaderValue;
use crate::wit;
pub struct Headers(wit::Headers);
pub type SubgraphHeaders = Headers;
pub type GatewayHeaders = Headers;
impl From<wit::Headers> for Headers {
fn from(headers: wit::Headers) -> Self {
Self(headers)
}
}
impl From<Headers> for wit::Headers {
fn from(headers: Headers) -> Self {
headers.0
}
}
impl Default for Headers {
fn default() -> Self {
Headers::new()
}
}
impl Headers {
pub fn new() -> Headers {
Headers(wit::Headers::new())
}
pub fn get(&self, name: impl AsHeaderName) -> Option<http::HeaderValue> {
self.0
.get(name.as_str())
.into_iter()
.next()
.map(|value| value.try_into().unwrap())
}
pub fn get_all(&self, name: impl AsHeaderName) -> impl Iterator<Item = http::HeaderValue> {
self.0
.get(name.as_str())
.into_iter()
.map(|value| value.try_into().unwrap())
}
pub fn has(&self, name: impl AsHeaderName) -> bool {
self.0.has(name.as_str())
}
pub fn set<V: AsHeaderValue>(&mut self, name: impl AsHeaderName, values: impl IntoIterator<Item = V>) {
let values = values
.into_iter()
.map(|value| value.as_bytes().to_vec())
.collect::<Vec<_>>();
self.0
.set(name.as_str(), &values)
.expect("We have a mut ref & validated name and values.");
}
pub fn remove(&mut self, name: impl AsHeaderName) -> Option<http::HeaderValue> {
self.0
.get_and_delete(name.as_str())
.map(|values| values.into_iter().next().map(|value| value.try_into().unwrap()))
.expect("We have a mut ref & validated name and values.")
}
pub fn append(&mut self, name: impl AsHeaderName, value: impl AsHeaderValue) {
self.0
.append(name.as_str(), value.as_bytes())
.expect("We have a mut ref & validated name and values.");
}
pub fn iter(&self) -> impl Iterator<Item = (http::HeaderName, http::HeaderValue)> {
self.0
.entries()
.into_iter()
.map(|(name, value)| (name.try_into().unwrap(), value.try_into().unwrap()))
}
}
impl From<&Headers> for http::HeaderMap {
fn from(headers: &Headers) -> Self {
headers.iter().collect()
}
}
mod as_header_name {
use http::HeaderName;
pub trait AsHeaderName: Sealed {}
pub trait Sealed {
#[doc(hidden)]
fn as_str(&self) -> &str;
}
impl Sealed for HeaderName {
#[inline]
fn as_str(&self) -> &str {
HeaderName::as_str(self)
}
}
impl AsHeaderName for HeaderName {}
impl Sealed for &HeaderName {
#[inline]
fn as_str(&self) -> &str {
HeaderName::as_str(self)
}
}
impl AsHeaderName for &HeaderName {}
impl Sealed for &str {
#[inline]
fn as_str(&self) -> &str {
self
}
}
impl AsHeaderName for &str {}
impl Sealed for String {
#[inline]
fn as_str(&self) -> &str {
String::as_str(self)
}
}
impl AsHeaderName for String {}
impl Sealed for &String {
#[inline]
fn as_str(&self) -> &str {
String::as_str(self)
}
}
impl AsHeaderName for &String {}
}
mod as_header_value {
use http::HeaderValue;
pub trait AsHeaderValue: Sealed {}
pub trait Sealed: Sized {
#[doc(hidden)]
fn as_bytes(&self) -> &[u8];
fn into_bytes(self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
impl Sealed for HeaderValue {
#[inline]
fn as_bytes(&self) -> &[u8] {
HeaderValue::as_bytes(self)
}
}
impl AsHeaderValue for HeaderValue {}
impl Sealed for &HeaderValue {
#[inline]
fn as_bytes(&self) -> &[u8] {
HeaderValue::as_bytes(self)
}
}
impl AsHeaderValue for &HeaderValue {}
impl Sealed for &[u8] {
#[inline]
fn as_bytes(&self) -> &[u8] {
self
}
}
impl AsHeaderValue for &[u8] {}
impl Sealed for &str {
#[inline]
fn as_bytes(&self) -> &[u8] {
str::as_bytes(self)
}
}
impl AsHeaderValue for &str {}
impl Sealed for String {
#[inline]
fn as_bytes(&self) -> &[u8] {
String::as_bytes(self)
}
fn into_bytes(self) -> Vec<u8> {
String::into_bytes(self)
}
}
impl AsHeaderValue for String {}
impl Sealed for &String {
#[inline]
fn as_bytes(&self) -> &[u8] {
String::as_bytes(self)
}
}
impl AsHeaderValue for &String {}
impl Sealed for Vec<u8> {
#[inline]
fn as_bytes(&self) -> &[u8] {
Vec::<u8>::as_ref(self)
}
fn into_bytes(self) -> Vec<u8> {
self
}
}
impl AsHeaderValue for Vec<u8> {}
impl Sealed for &Vec<u8> {
#[inline]
fn as_bytes(&self) -> &[u8] {
Vec::<u8>::as_ref(self)
}
}
impl AsHeaderValue for &Vec<u8> {}
}