Merge pull request #95 from slinkydeveloper/docs

Another round of docs fix + cleanups
This commit is contained in:
Lazzaretti 2020-11-01 08:40:47 +01:00 committed by GitHub
commit e6500338c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 221 additions and 117 deletions

View File

@ -11,6 +11,7 @@ repository = "https://github.com/cloudevents/sdk-rust"
exclude = [
".github/*"
]
categories = ["web-programming", "encoding", "data-structures"]
[lib]
name = "cloudevents"
@ -36,6 +37,7 @@ uuid = { version = "^0.8", features = ["v4", "wasm-bindgen"] }
[dev-dependencies]
rstest = "0.6"
claim = "0.3.1"
version-sync = "^0.9"
[workspace]
members = [

View File

@ -30,6 +30,7 @@ Note: This project is WIP under active development, hence all APIs are considere
To get started, add the dependency to `Cargo.toml`:
```toml
[dependencies]
cloudevents-sdk = "0.2.0"
```
@ -43,8 +44,7 @@ let event = EventBuilderV10::new()
.id("aaa")
.source(Url::parse("http://localhost").unwrap())
.ty("example.demo")
.build()
.unwrap();
.build()?;
```
Checkout the examples using our integrations to learn how to send and receive events:

View File

@ -8,6 +8,7 @@ description = "CloudEvents official Rust SDK - Actix-Web integration"
documentation = "https://docs.rs/cloudevents-sdk-actix-web"
repository = "https://github.com/cloudevents/sdk-rust"
readme = "README.md"
categories = ["web-programming", "encoding", "web-programming::http-server"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -23,4 +24,5 @@ futures = "^0.3"
[dev-dependencies]
url = { version = "^2.1", features = ["serde"] }
serde_json = "^1.0"
chrono = { version = "^0.4", features = ["serde"] }
chrono = { version = "^0.4", features = ["serde"] }
version-sync = "^0.9"

View File

@ -3,7 +3,7 @@
//! To deserialize an HTTP request as CloudEvent:
//!
//! ```
//! use cloudevents_sdk_actix_web::RequestExt;
//! use cloudevents_sdk_actix_web::HttpRequestExt;
//! use actix_web::{HttpRequest, web, post};
//!
//! #[post("/")]
@ -41,6 +41,9 @@
//!
//! Check out the [cloudevents-sdk](https://docs.rs/cloudevents-sdk) docs for more details on how to use [`cloudevents::Event`]
#![doc(html_root_url = "https://docs.rs/cloudevents-sdk-actix-web/0.2.0")]
#![deny(broken_intra_doc_links)]
#[macro_use]
mod headers;
mod server_request;
@ -48,7 +51,7 @@ mod server_response;
pub use server_request::request_to_event;
pub use server_request::HttpRequestDeserializer;
pub use server_request::RequestExt;
pub use server_request::HttpRequestExt;
pub use server_response::event_to_response;
pub use server_response::HttpResponseBuilderExt;
pub use server_response::HttpResponseSerializer;

View File

@ -113,8 +113,11 @@ pub async fn request_to_event(
}
/// Extention Trait for [`HttpRequest`] which acts as a wrapper for the function [`request_to_event()`].
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
#[async_trait(?Send)]
pub trait RequestExt {
pub trait HttpRequestExt: private::Sealed {
/// Convert this [`HttpRequest`] into an [`Event`].
async fn to_event(
&self,
mut payload: web::Payload,
@ -122,7 +125,7 @@ pub trait RequestExt {
}
#[async_trait(?Send)]
impl RequestExt for HttpRequest {
impl HttpRequestExt for HttpRequest {
async fn to_event(
&self,
payload: web::Payload,
@ -131,6 +134,12 @@ impl RequestExt for HttpRequest {
}
}
mod private {
// Sealing the RequestExt
pub trait Sealed {}
impl Sealed for actix_web::HttpRequest {}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -76,9 +76,12 @@ pub async fn event_to_response(
.map_err(actix_web::error::ErrorBadRequest)
}
/// Extention Trait for [`HttpResponseBuilder`] which acts as a wrapper for the function [`event_to_response()`].
/// Extension Trait for [`HttpResponseBuilder`] which acts as a wrapper for the function [`event_to_response()`].
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
#[async_trait(?Send)]
pub trait HttpResponseBuilderExt {
pub trait HttpResponseBuilderExt: private::Sealed {
/// Fill this [`HttpResponseBuilder`] with an [`Event`].
async fn event(
self,
event: Event,
@ -95,6 +98,12 @@ impl HttpResponseBuilderExt for HttpResponseBuilder {
}
}
// Sealing the HttpResponseBuilderExt
mod private {
pub trait Sealed {}
impl Sealed for actix_web::dev::HttpResponseBuilder {}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -0,0 +1,9 @@
#[test]
fn test_readme_deps() {
version_sync::assert_markdown_deps_updated!("README.md");
}
#[test]
fn test_html_root_url() {
version_sync::assert_html_root_url_updated!("src/lib.rs");
}

View File

@ -8,6 +8,7 @@ description = "CloudEvents official Rust SDK - Kafka integration"
documentation = "https://docs.rs/cloudevents-sdk-rdkafka"
repository = "https://github.com/cloudevents/sdk-rust"
readme = "README.md"
categories = ["web-programming", "encoding"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -15,11 +16,12 @@ readme = "README.md"
bytes = "^0.5"
cloudevents-sdk = { version = "0.2.0", path = ".." }
lazy_static = "1.4.0"
rdkafka = { version = "^0.24", features = ["cmake-build"] }
rdkafka = { version = "^0.24", default-features = false }
[dev-dependencies]
url = { version = "^2.1" }
serde_json = "^1.0"
chrono = { version = "^0.4", features = ["serde"] }
futures = "0.3.5"
rdkafka = { version = "^0.24" }
version-sync = "^0.9"

View File

@ -134,8 +134,10 @@ pub fn record_to_event(msg: &impl Message) -> Result<Event> {
MessageDeserializer::into_event(ConsumerRecordDeserializer::new(msg)?)
}
/// Extension Trait for [`Message`] which acts as a wrapper for the function [`record_to_event()`]
pub trait MessageExt {
/// Extension Trait for [`Message`] which acts as a wrapper for the function [`record_to_event()`].
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
pub trait MessageExt: private::Sealed {
/// Generates [`Event`] from [`BorrowedMessage`].
fn to_event(&self) -> Result<Event>;
}
@ -152,6 +154,13 @@ impl MessageExt for OwnedMessage {
}
}
mod private {
// Sealing the MessageExt
pub trait Sealed {}
impl Sealed for rdkafka::message::OwnedMessage {}
impl Sealed for rdkafka::message::BorrowedMessage<'_> {}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -88,7 +88,9 @@ impl StructuredSerializer<MessageRecord> for MessageRecord {
}
/// Extension Trait for [`BaseRecord`] that fills the record with a [`MessageRecord`].
pub trait BaseRecordExt<'a, K: ToBytes + ?Sized> {
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
pub trait BaseRecordExt<'a, K: ToBytes + ?Sized>: private::Sealed {
/// Fill this [`BaseRecord`] with a [`MessageRecord`].
fn message_record(
self,
@ -112,7 +114,9 @@ impl<'a, K: ToBytes + ?Sized> BaseRecordExt<'a, K> for BaseRecord<'a, K, Vec<u8>
}
/// Extension Trait for [`FutureRecord`] that fills the record with a [`MessageRecord`].
pub trait FutureRecordExt<'a, K: ToBytes + ?Sized> {
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
pub trait FutureRecordExt<'a, K: ToBytes + ?Sized>: private::Sealed {
/// Fill this [`FutureRecord`] with a [`MessageRecord`].
fn message_record(self, message_record: &'a MessageRecord) -> FutureRecord<'a, K, Vec<u8>>;
}
@ -128,3 +132,16 @@ impl<'a, K: ToBytes + ?Sized> FutureRecordExt<'a, K> for FutureRecord<'a, K, Vec
self
}
}
mod private {
// Sealing the FutureRecordExt and BaseRecordExt
pub trait Sealed {}
impl<K: rdkafka::message::ToBytes + ?Sized, V: rdkafka::message::ToBytes> Sealed
for rdkafka::producer::FutureRecord<'_, K, V>
{
}
impl<K: rdkafka::message::ToBytes + ?Sized, V: rdkafka::message::ToBytes> Sealed
for rdkafka::producer::BaseRecord<'_, K, V>
{
}
}

View File

@ -10,9 +10,8 @@
//! use rdkafka::util::Timeout;
//! use cloudevents_sdk_rdkafka::{MessageRecord, FutureRecordExt};
//!
//! # async fn produce(producer: &FutureProducer, event: Event) {
//! let message_record = MessageRecord::from_event(event)
//! .expect("error while serializing the event");
//! # async fn produce(producer: &FutureProducer, event: Event) -> Result<(), Box<dyn std::error::Error>> {
//! let message_record = MessageRecord::from_event(event)?;
//!
//! producer.send(
//! FutureRecord::to("topic")
@ -20,7 +19,7 @@
//! .message_record(&message_record),
//! Timeout::Never
//! ).await;
//!
//! # Ok(())
//! # }
//!
//! ```
@ -32,22 +31,26 @@
//! use cloudevents_sdk_rdkafka::MessageExt;
//! use futures::StreamExt;
//!
//! # async fn consume(consumer: StreamConsumer<DefaultConsumerContext>) {
//! # async fn consume(consumer: StreamConsumer<DefaultConsumerContext>) -> Result<(), Box<dyn std::error::Error>> {
//! let mut message_stream = consumer.start();
//!
//! while let Some(message) = message_stream.next().await {
//! match message {
//! Err(e) => println!("Kafka error: {}", e),
//! Ok(m) => {
//! let event = m.to_event().expect("error while deserializing record to CloudEvent");
//! println!("Received Event: {:#?}", event);
//! consumer.commit_message(&m, CommitMode::Async).unwrap();
//! let event = m.to_event()?;
//! println!("Received Event: {}", event);
//! consumer.commit_message(&m, CommitMode::Async)?;
//! }
//! };
//! }
//! # Ok(())
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/cloudevents-sdk-rdkafka/0.2.0")]
#![deny(broken_intra_doc_links)]
#[macro_use]
mod headers;
mod kafka_consumer_record;

View File

@ -0,0 +1,9 @@
#[test]
fn test_readme_deps() {
version_sync::assert_markdown_deps_updated!("README.md");
}
#[test]
fn test_html_root_url() {
version_sync::assert_html_root_url_updated!("src/lib.rs");
}

View File

@ -8,6 +8,7 @@ description = "CloudEvents official Rust SDK - Reqwest integration"
documentation = "https://docs.rs/cloudevents-sdk-reqwest"
repository = "https://github.com/cloudevents/sdk-rust"
readme = "README.md"
categories = ["web-programming", "encoding", "web-programming::http-client"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -27,4 +28,5 @@ mockito = "0.25.1"
tokio = { version = "^0.2", features = ["full"] }
url = { version = "^2.1" }
serde_json = "^1.0"
chrono = { version = "^0.4", features = ["serde"] }
chrono = { version = "^0.4", features = ["serde"] }
version-sync = "^0.9"

View File

@ -62,13 +62,16 @@ impl StructuredSerializer<RequestBuilder> for RequestSerializer {
}
}
/// Method to fill a [`RequestBuilder`] with an [`Event`]
/// Method to fill a [`RequestBuilder`] with an [`Event`].
pub fn event_to_request(event: Event, request_builder: RequestBuilder) -> Result<RequestBuilder> {
BinaryDeserializer::deserialize_binary(event, RequestSerializer::new(request_builder))
}
/// Extention Trait for [`RequestBuilder`] which acts as a wrapper for the function [`event_to_request()`]
pub trait RequestBuilderExt {
/// Extension Trait for [`RequestBuilder`] which acts as a wrapper for the function [`event_to_request()`].
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
pub trait RequestBuilderExt: private::Sealed {
/// Write in this [`RequestBuilder`] the provided [`Event`]. Similar to invoking [`Event`].
fn event(self, event: Event) -> Result<RequestBuilder>;
}
@ -78,6 +81,12 @@ impl RequestBuilderExt for RequestBuilder {
}
}
// Sealing the RequestBuilderExt
mod private {
pub trait Sealed {}
impl Sealed for reqwest::RequestBuilder {}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -109,8 +109,11 @@ pub async fn response_to_event(res: Response) -> Result<Event> {
}
/// Extension Trait for [`Response`] which acts as a wrapper for the function [`response_to_event()`].
///
/// This trait is sealed and cannot be implemented for types outside of this crate.
#[async_trait(?Send)]
pub trait ResponseExt {
pub trait ResponseExt: private::Sealed {
/// Convert this [`Response`] to [`Event`].
async fn into_event(self) -> Result<Event>;
}
@ -121,6 +124,12 @@ impl ResponseExt for Response {
}
}
// Sealing the ResponseExt
mod private {
pub trait Sealed {}
impl Sealed for reqwest::Response {}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -5,7 +5,7 @@
//! use cloudevents::{EventBuilderV10, EventBuilder};
//! use serde_json::json;
//!
//! # async fn example() {
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let client = reqwest::Client::new();
//!
//! // Prepare the event to send
@ -14,23 +14,23 @@
//! .ty("example.test")
//! .source("http://localhost/")
//! .data("application/json", json!({"hello": "world"}))
//! .build()
//! .expect("No error while building the event");
//! .build()?;
//!
//! // Send request
//! let response = client.post("http://localhost")
//! .event(event_to_send)
//! .expect("Error while serializing the event")
//! .send().await
//! .expect("Error while sending the request");
//! .event(event_to_send)?
//! .send().await?;
//! // Parse response as event
//! let received_event = response
//! .into_event().await
//! .expect("Error while deserializing the response");
//! .into_event().await?;
//! # Ok(())
//! # }
//! ```
//!
//! Check out the [cloudevents-sdk](https://docs.rs/cloudevents-sdk) docs for more details on how to use [`cloudevents::Event`]
//! Check out the [cloudevents-sdk](https://docs.rs/cloudevents-sdk) docs for more details on how to use [`cloudevents::Event`].
#![doc(html_root_url = "https://docs.rs/cloudevents-sdk-reqwest/0.2.0")]
#![deny(broken_intra_doc_links)]
#[macro_use]
mod headers;

View File

@ -0,0 +1,9 @@
#[test]
fn test_readme_deps() {
version_sync::assert_markdown_deps_updated!("README.md");
}
#[test]
fn test_html_root_url() {
version_sync::assert_html_root_url_updated!("src/lib.rs");
}

View File

@ -7,9 +7,9 @@ edition = "2018"
[dependencies]
cloudevents-sdk = { path = "../.." }
cloudevents-sdk-actix-web = { path = "../../cloudevents-sdk-actix-web" }
actix-web = "2"
actix-web = "^3"
actix-rt = "1"
actix-cors = "^0.2.0"
actix-cors = "^0.5"
lazy_static = "1.4.0"
bytes = "^0.5"
futures = "^0.3"

View File

@ -1,6 +1,6 @@
use actix_web::{get, post, web, App, HttpRequest, HttpResponse, HttpServer};
use cloudevents::{EventBuilder, EventBuilderV10};
use cloudevents_sdk_actix_web::{HttpResponseBuilderExt, RequestExt};
use cloudevents_sdk_actix_web::{HttpResponseBuilderExt, HttpRequestExt};
use serde_json::json;
#[post("/")]
@ -36,7 +36,7 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(actix_web::middleware::Logger::default())
.wrap(actix_cors::Cors::new().finish())
.wrap(actix_cors::Cors::permissive())
.service(post_event)
.service(get_event)
})

View File

@ -19,5 +19,7 @@ tokio = { version = "^0.2", features = ["full"] }
clap = "2.33.1"
[dependencies.rdkafka]
version = "~0.23"
features = ["ssl", "sasl"]
version = "^0.24"
features = ["cmake-build"]
[workspace]

View File

@ -9,6 +9,7 @@ use rdkafka::config::{ClientConfig, RDKafkaLogLevel};
use rdkafka::consumer::stream_consumer::StreamConsumer;
use rdkafka::consumer::{CommitMode, Consumer, DefaultConsumerContext};
use rdkafka::producer::{FutureProducer, FutureRecord};
use std::time::Duration;
// You need a running Kafka cluster to try out this example.
// With docker: docker run --rm --net=host -e ADV_HOST=localhost -e SAMPLEDATA=0 lensesio/fast-data-dev
@ -78,7 +79,7 @@ async fn produce(brokers: &str, topic_name: &str) {
FutureRecord::to(topic_name)
.message_record(&message_record)
.key(&format!("Key {}", i)),
0,
Duration::from_secs(10),
)
.await;

View File

@ -7,7 +7,8 @@ use serde::Serializer;
use std::fmt;
use url::Url;
/// Value of a CloudEvent attribute
/// Enum representing a borrowed value of a CloudEvent attribute.
/// This represents the types defined in the [CloudEvent spec type system](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system)
#[derive(Debug, PartialEq, Eq)]
pub enum AttributeValue<'a> {
SpecVersion(SpecVersion),
@ -230,20 +231,20 @@ impl AttributesWriter for Attributes {
}
impl Attributes {
pub fn into_v10(self) -> Self {
pub(crate) fn into_v10(self) -> Self {
match self {
Attributes::V03(v03) => Attributes::V10(v03.into_v10()),
_ => self,
}
}
pub fn into_v03(self) -> Self {
pub(crate) fn into_v03(self) -> Self {
match self {
Attributes::V10(v10) => Attributes::V03(v10.into_v03()),
_ => self,
}
}
pub fn iter(&self) -> impl Iterator<Item = (&str, AttributeValue)> {
pub(crate) fn iter(&self) -> impl Iterator<Item = (&str, AttributeValue)> {
match self {
Attributes::V03(a) => AttributesIter::IterV03(a.into_iter()),
Attributes::V10(a) => AttributesIter::IterV10(a.into_iter()),

View File

@ -1,6 +1,6 @@
use serde::export::Formatter;
use serde_json::Value;
use std::convert::{Into, TryFrom};
use std::convert::TryFrom;
use std::fmt;
/// Event [data attribute](https://github.com/cloudevents/spec/blob/master/spec.md#event-data) representation
@ -14,40 +14,6 @@ pub enum Data {
Json(serde_json::Value),
}
impl Data {
/// Create a [`Data`] from a [`Into<Vec<u8>>`].
///
/// # Example
///
/// ```
/// use cloudevents::event::Data;
///
/// let value = Data::from_base64(b"dmFsdWU=").unwrap();
/// assert_eq!(value, Data::Binary(base64::decode("dmFsdWU=").unwrap()));
/// ```
///
/// [`AsRef<[u8]>`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html
/// [`Data`]: enum.Data.html
pub fn from_base64<I>(i: I) -> Result<Self, base64::DecodeError>
where
I: AsRef<[u8]>,
{
Ok(base64::decode(&i)?.into())
}
pub fn from_binary<I>(content_type: Option<&str>, i: I) -> Result<Self, serde_json::Error>
where
I: AsRef<[u8]>,
{
let is_json = is_json_content_type(content_type.unwrap_or("application/json"));
if is_json {
serde_json::from_slice::<serde_json::Value>(i.as_ref()).map(Data::Json)
} else {
Ok(Data::Binary(i.as_ref().to_vec()))
}
}
}
pub(crate) fn is_json_content_type(ct: &str) -> bool {
ct.starts_with("application/json") || ct.starts_with("text/json") || ct.ends_with("+json")
}

View File

@ -6,11 +6,11 @@ use std::fmt;
#[serde(untagged)]
/// Represents all the possible [CloudEvents extension](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) values
pub enum ExtensionValue {
/// Represents a [`String`](std::string::String) value.
/// Represents a [`String`] value.
String(String),
/// Represents a [`bool`](bool) value.
/// Represents a [`bool`] value.
Boolean(bool),
/// Represents an integer [`i64`](i64) value.
/// Represents an integer [`i64`] value.
Integer(i64),
}

View File

@ -1,3 +1,5 @@
//! Provides [`Event`] data structure, [`EventBuilder`] and other facilities to work with [`Event`].
mod attributes;
mod builder;
mod data;

View File

@ -5,14 +5,18 @@ use std::fmt;
pub(crate) const SPEC_VERSIONS: [&'static str; 2] = ["0.3", "1.0"];
/// CloudEvent specification version
/// CloudEvent specification version.
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum SpecVersion {
/// CloudEvents v0.3
V03,
/// CloudEvents v1.0
V10,
}
impl SpecVersion {
/// Returns the string representation of [`SpecVersion`].
#[inline]
pub fn as_str(&self) -> &str {
match self {
SpecVersion::V03 => "0.3",
@ -28,7 +32,7 @@ impl SpecVersion {
SpecVersion::V10 => &v10::ATTRIBUTE_NAMES,
}
}
/// Get all attribute names for all Spec versions.
/// Get all attribute names for all specification versions.
/// Note that the result iterator could contain duplicate entries.
pub fn all_attribute_names() -> impl Iterator<Item = &'static str> {
vec![SpecVersion::V03, SpecVersion::V10]

View File

@ -1,8 +1,10 @@
//! This crate implements the [CloudEvents](https://cloudevents.io/) Spec for Rust.
//!
//! ```
//! # use std::error::Error;
//! # fn main() -> Result<(), Box<dyn Error>> {
//! use cloudevents::{EventBuilder, AttributesReader, EventBuilderV10};
//! use chrono::Utc;
//! use chrono::{Utc, DateTime};
//! use url::Url;
//!
//! let event = EventBuilderV10::new()
@ -10,27 +12,35 @@
//! .source("http://localhost:8080")
//! .ty("example.demo")
//! .time(Utc::now())
//! .build()
//! .unwrap();
//! .build()?;
//!
//! println!("CloudEvent Id: {}", event.id());
//! println!("CloudEvent Time: {}", event.time().unwrap());
//! match event.time() {
//! Some(t) => println!("CloudEvent Time: {}", t),
//! None => println!("CloudEvent Time: None")
//! }
//! # Ok(())
//! # }
//! ```
//!
//! This crate includes:
//!
//! * The [`Event`] data structure, to represent CloudEvent (version 1.0 and 0.3)
//! * The [`EventBuilder`] trait and implementations, to create [`Event`] instances
//! * The implementation of [`serde::Serialize`] and [`serde::Deserialize`] for [`Event`] to serialize/deserialize CloudEvents to/from JSON
//! * Traits and utilities in [`message`] to implement Protocol Bindings
//!
//! If you're looking for Protocol Binding implementations, look at crates:
//!
//! * [cloudevents-sdk-actix-web](https://docs.rs/cloudevents-sdk-actix-web): Integration with [Actix Web](https://github.com/actix/actix-web)
//! * [cloudevents-sdk-reqwest](https://docs.rs/cloudevents-sdk-reqwest): Integration with [reqwest](https://github.com/seanmonstar/reqwest)
//! * [cloudevents-sdk-rdkafka](https://docs.rs/cloudevents-sdk-rdkafka): Integration with [rdkafka](https://fede1024.github.io/rust-rdkafka)
//!
extern crate serde;
extern crate serde_json;
extern crate serde_value;
extern crate snafu;
#![doc(html_root_url = "https://docs.rs/cloudevents-sdk/0.2.0")]
#![deny(broken_intra_doc_links)]
/// Provides [`Event`] data structure, [`EventBuilder`] and other facilities to work with [`Event`]
pub mod event;
/// Provides facilities to implement Protocol Bindings
pub mod message;
pub use event::Data;

View File

@ -2,46 +2,46 @@ use super::{BinarySerializer, Encoding, Error, Result, StructuredSerializer};
use crate::event::{EventBinarySerializer, EventStructuredSerializer};
use crate::Event;
/// Deserializer trait for a Message that can be encoded as structured mode
/// Deserializer trait for a Message that can be encoded as structured mode.
pub trait StructuredDeserializer
where
Self: Sized,
{
/// Deserialize the message to [`StructuredSerializer`]
/// Deserialize the message to [`StructuredSerializer`].
fn deserialize_structured<R: Sized, V: StructuredSerializer<R>>(
self,
serializer: V,
) -> Result<R>;
/// Convert this Message to [`Event`]
/// Convert this Message to [`Event`].
fn into_event(self) -> Result<Event> {
self.deserialize_structured(EventStructuredSerializer {})
}
}
/// Deserializer trait for a Message that can be encoded as binary mode
/// Deserializer trait for a Message that can be encoded as binary mode.
pub trait BinaryDeserializer
where
Self: Sized,
{
/// Deserialize the message to [`BinarySerializer`]
/// Deserialize the message to [`BinarySerializer`].
fn deserialize_binary<R: Sized, V: BinarySerializer<R>>(self, serializer: V) -> Result<R>;
/// Convert this Message to [`Event`]
/// Convert this Message to [`Event`].
fn into_event(self) -> Result<Event> {
self.deserialize_binary(EventBinarySerializer::new())
}
}
/// Deserializer trait for a Message that can be encoded both in structured mode or binary mode
/// Deserializer trait for a Message that can be encoded both in structured mode or binary mode.
pub trait MessageDeserializer
where
Self: StructuredDeserializer + BinaryDeserializer + Sized,
{
/// Get this message [`Encoding`]
/// Get this message [`Encoding`].
fn encoding(&self) -> Encoding;
/// Convert this Message to [`Event`]
/// Convert this Message to [`Event`].
fn into_event(self) -> Result<Event> {
match self.encoding() {
Encoding::BINARY => BinaryDeserializer::into_event(self),
@ -50,7 +50,7 @@ where
}
}
/// Deserialize the message to [`BinarySerializer`]
/// Deserialize the message to [`BinarySerializer`].
fn deserialize_to_binary<R: Sized, T: BinarySerializer<R>>(self, serializer: T) -> Result<R> {
if self.encoding() == Encoding::BINARY {
return self.deserialize_binary(serializer);
@ -59,7 +59,7 @@ where
return MessageDeserializer::into_event(self)?.deserialize_binary(serializer);
}
/// Deserialize the message to [`StructuredSerializer`]
/// Deserialize the message to [`StructuredSerializer`].
fn deserialize_to_structured<R: Sized, T: StructuredSerializer<R>>(
self,
serializer: T,
@ -71,8 +71,8 @@ where
return MessageDeserializer::into_event(self)?.deserialize_structured(serializer);
}
/// Deserialize the message to a serializer, depending on the message encoding
/// You can use this method to transcode this message directly to another serializer, without going through [`Event`]
/// Deserialize the message to a serializer, depending on the message encoding.
/// You can use this method to transcode this message directly to another serializer, without going through [`Event`].
fn deserialize_to<R: Sized, T: BinarySerializer<R> + StructuredSerializer<R>>(
self,
serializer: T,

View File

@ -1,9 +1,12 @@
use std::fmt::Debug;
/// Represents one of the possible [message encodings/modes](https://github.com/cloudevents/spec/blob/v1.0/spec.md#message)
/// Represents one of the possible [message encodings/modes](https://github.com/cloudevents/spec/blob/v1.0/spec.md#message).
#[derive(PartialEq, Eq, Debug)]
pub enum Encoding {
/// Represents the _structured-mode message_.
STRUCTURED,
/// Represents the _binary-mode message_.
BINARY,
/// Represents a non-CloudEvent or a malformed CloudEvent that cannot be recognized by the SDK.
UNKNOWN,
}

View File

@ -1,3 +1,7 @@
//! Provides facilities to implement Protocol Bindings.
//!
//! Note: these APIs should be considered unstable and subject to changes.
mod deserializer;
mod encoding;
mod error;

View File

@ -1,12 +1,12 @@
use super::{MessageAttributeValue, Result};
use crate::event::SpecVersion;
/// Serializer for structured mode messages
/// Serializer for structured mode messages.
pub trait StructuredSerializer<RETURN: Sized> {
fn set_structured_event(self, bytes: Vec<u8>) -> Result<RETURN>;
}
/// Serializer for binary mode messages
/// Serializer for binary mode messages.
pub trait BinarySerializer<RETURN: Sized>
where
Self: Sized,

View File

@ -1,11 +1,10 @@
use crate::event::ExtensionValue;
use chrono::{DateTime, Utc};
use serde::export::Formatter;
use std::convert::TryInto;
use std::fmt;
use url::Url;
/// Union type representing a [CloudEvent context attribute type](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system)
/// Union type representing a [CloudEvent context attribute type](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system).
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum MessageAttributeValue {
Boolean(bool),

9
tests/version_number.rs Normal file
View File

@ -0,0 +1,9 @@
#[test]
fn test_readme_deps() {
version_sync::assert_markdown_deps_updated!("README.md");
}
#[test]
fn test_html_root_url() {
version_sync::assert_html_root_url_updated!("src/lib.rs");
}