Add support for core http crate binding
Signed-off-by: Dejan Bosanac <dejan@sensatic.net>
This commit is contained in:
		
							parent
							
								
									62b895c025
								
							
						
					
					
						commit
						0741f2bf28
					
				|  | @ -17,6 +17,7 @@ categories = ["web-programming", "encoding", "data-structures"] | |||
| name = "cloudevents" | ||||
| 
 | ||||
| [features] | ||||
| http-binding = ["async-trait", "bytes", "futures", "http"] | ||||
| actix = ["actix-web", "async-trait", "bytes", "futures", "http"] | ||||
| reqwest = ["reqwest-lib", "async-trait", "bytes", "http"] | ||||
| rdkafka = ["rdkafka-lib", "bytes", "futures"] | ||||
|  | @ -43,17 +44,20 @@ bytes = { version = "^1.0", optional = true } | |||
| futures = { version = "^0.3", optional = true } | ||||
| http = { version = "0.2", optional = true } | ||||
| hyper = { version = "^0.14", optional = true } | ||||
| axum-lib = { version = "^0.2", optional = true , package="axum"} | ||||
| axum-lib = { version = "^0.2", optional = true, package="axum"} | ||||
| http-body = { version = "^0.4", optional = true} | ||||
| 
 | ||||
| [target."cfg(not(target_arch = \"wasm32\"))".dependencies] | ||||
| hostname = "^0.3" | ||||
| uuid = { version = "^0.8", features = ["v4"] } | ||||
| 
 | ||||
| [target.'cfg(target_arch = "wasm32")'.dependencies] | ||||
| [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] | ||||
| web-sys = { version = "^0.3", features = ["Window", "Location"] } | ||||
| uuid = { version = "^0.8", features = ["v4", "wasm-bindgen"] } | ||||
| 
 | ||||
| [target.'cfg(all(target_arch = "wasm32", target_os="wasi"))'.dependencies] | ||||
| uuid = { version = "^0.8", features = ["v4"] } | ||||
| 
 | ||||
| [dev-dependencies] | ||||
| rstest = "0.6" | ||||
| claim = "0.3.1" | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| pub mod builder; | ||||
| mod deserializer; | ||||
| pub mod deserializer; | ||||
| mod headers; | ||||
| 
 | ||||
| use crate::{ | ||||
|  | @ -11,7 +11,11 @@ pub use headers::Headers; | |||
| mod serializer; | ||||
| 
 | ||||
| pub use builder::Builder; | ||||
| use core::convert::TryFrom; | ||||
| use http::Response; | ||||
| pub use serializer::Serializer; | ||||
| use std::convert::TryInto; | ||||
| use std::fmt::Debug; | ||||
| 
 | ||||
| pub static SPEC_VERSION_HEADER: &str = "ce-specversion"; | ||||
| 
 | ||||
|  | @ -26,3 +30,42 @@ pub fn to_event<'a, T: Headers<'a>>( | |||
| pub fn header_prefix(name: &str) -> String { | ||||
|     super::header_prefix("ce-", name) | ||||
| } | ||||
| 
 | ||||
| impl<T> TryFrom<Response<T>> for Event | ||||
| where | ||||
|     T: TryInto<Vec<u8>>, | ||||
|     <T as TryInto<Vec<u8>>>::Error: Debug, | ||||
| { | ||||
|     type Error = crate::message::Error; | ||||
| 
 | ||||
|     fn try_from(response: Response<T>) -> Result<Self, Self::Error> { | ||||
|         let headers = response.headers().to_owned(); | ||||
|         let body = T::try_into(response.into_body()).unwrap(); | ||||
| 
 | ||||
|         to_event(&headers, body) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::test::fixtures; | ||||
|     use crate::Event; | ||||
|     use core::convert::TryFrom; | ||||
|     use http::Response; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_response_to_event() { | ||||
|         let event = fixtures::v10::minimal_string_extension(); | ||||
| 
 | ||||
|         let response = Response::builder() | ||||
|             .header("ce-id", fixtures::id()) | ||||
|             .header("ce-source", fixtures::source()) | ||||
|             .header("ce-type", fixtures::ty()) | ||||
|             .header("ce-specversion", "1.0") | ||||
|             .header("ce-someint", "10") | ||||
|             .body(Vec::new()) | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         assert_eq!(event, Event::try_from(response).unwrap()); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,14 @@ use crate::binding::{ | |||
|     CLOUDEVENTS_JSON_HEADER, | ||||
| }; | ||||
| use crate::event::SpecVersion; | ||||
| use crate::message::{BinarySerializer, MessageAttributeValue, Result, StructuredSerializer}; | ||||
| use crate::message::BinaryDeserializer; | ||||
| use crate::message::{ | ||||
|     BinarySerializer, Error, MessageAttributeValue, Result, StructuredSerializer, | ||||
| }; | ||||
| use crate::Event; | ||||
| use http::Request; | ||||
| use std::convert::TryFrom; | ||||
| use std::fmt::Debug; | ||||
| 
 | ||||
| macro_rules! str_to_header_value { | ||||
|     ($header_value:expr) => { | ||||
|  | @ -70,3 +77,81 @@ impl<T> StructuredSerializer<T> for Serializer<T> { | |||
|         builder.body(bytes) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T> BinarySerializer<http::request::Request<Option<T>>> for http::request::Builder | ||||
| where | ||||
|     T: TryFrom<Vec<u8>>, | ||||
|     <T as TryFrom<Vec<u8>>>::Error: Debug, | ||||
| { | ||||
|     fn set_spec_version(mut self, sv: SpecVersion) -> Result<Self> { | ||||
|         self = self.header(SPEC_VERSION_HEADER, &sv.to_string()); | ||||
|         Ok(self) | ||||
|     } | ||||
| 
 | ||||
|     fn set_attribute(mut self, name: &str, value: MessageAttributeValue) -> Result<Self> { | ||||
|         let key = &header_prefix(name); | ||||
|         self = self.header(key, &value.to_string()); | ||||
|         Ok(self) | ||||
|     } | ||||
| 
 | ||||
|     fn set_extension(mut self, name: &str, value: MessageAttributeValue) -> Result<Self> { | ||||
|         let key = &header_prefix(name); | ||||
|         self = self.header(key, &value.to_string()); | ||||
|         Ok(self) | ||||
|     } | ||||
| 
 | ||||
|     fn end_with_data(self, bytes: Vec<u8>) -> Result<http::request::Request<Option<T>>> { | ||||
|         let body = T::try_from(bytes).unwrap(); | ||||
|         self.body(Some(body)).map_err(|e| Error::Other { | ||||
|             source: Box::new(e), | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn end(self) -> Result<http::request::Request<Option<T>>> { | ||||
|         self.body(None).map_err(|e| Error::Other { | ||||
|             source: Box::new(e), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T> TryFrom<Event> for Request<Option<T>> | ||||
| where | ||||
|     T: TryFrom<Vec<u8>>, | ||||
|     <T as TryFrom<Vec<u8>>>::Error: Debug, | ||||
| { | ||||
|     type Error = crate::message::Error; | ||||
| 
 | ||||
|     fn try_from(event: Event) -> Result<Self> { | ||||
|         BinaryDeserializer::deserialize_binary(event, http::request::Builder::new()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::test::fixtures; | ||||
|     use bytes::Bytes; | ||||
|     use http::Request; | ||||
|     use std::convert::TryFrom; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_event_to_http_request() { | ||||
|         let event = fixtures::v10::minimal_string_extension(); | ||||
|         let request: Request<Option<Vec<u8>>> = Request::try_from(event).unwrap(); | ||||
| 
 | ||||
|         assert_eq!(request.headers()["ce-id"], "0001"); | ||||
|         assert_eq!(request.headers()["ce-type"], "test_event.test_application"); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_event_to_bytes_body() { | ||||
|         let event = fixtures::v10::full_binary_json_data_string_extension(); | ||||
|         let request: Request<Option<Vec<u8>>> = Request::try_from(event).unwrap(); | ||||
| 
 | ||||
|         assert_eq!(request.headers()["ce-id"], "0001"); | ||||
|         assert_eq!(request.headers()["ce-type"], "test_event.test_application"); | ||||
|         assert_eq!( | ||||
|             request.body().as_ref().unwrap(), | ||||
|             &Bytes::from(fixtures::json_data().to_string()) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ pub mod actix; | |||
| #[cfg(feature = "axum")] | ||||
| pub mod axum; | ||||
| #[cfg(any(
 | ||||
|     feature = "http-binding", | ||||
|     feature = "actix", | ||||
|     feature = "warp", | ||||
|     feature = "reqwest", | ||||
|  |  | |||
|  | @ -268,7 +268,7 @@ pub(crate) fn default_hostname() -> Url { | |||
|     .unwrap() | ||||
| } | ||||
| 
 | ||||
| #[cfg(target_arch = "wasm32")] | ||||
| #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] | ||||
| pub(crate) fn default_hostname() -> Url { | ||||
|     use std::str::FromStr; | ||||
| 
 | ||||
|  | @ -281,3 +281,10 @@ pub(crate) fn default_hostname() -> Url { | |||
|     ) | ||||
|     .unwrap() | ||||
| } | ||||
| 
 | ||||
| #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] | ||||
| pub(crate) fn default_hostname() -> Url { | ||||
|     use std::str::FromStr; | ||||
| 
 | ||||
|     Url::from_str("http://localhost").unwrap() | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue