Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions .github/workflows/rust_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ jobs:
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --workspace
args: --target ${{ matrix.target }} --workspace --all-features
- uses: actions-rs/cargo@v1
name: "Test"
if: matrix.target == 'x86_64-unknown-linux-gnu'
with:
command: test
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --workspace
args: --target ${{ matrix.target }} --workspace --all-features

# If musl, compile and test all
- uses: actions-rs/cargo@v1
Expand All @@ -76,7 +76,7 @@ jobs:
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --workspace
args: --target ${{ matrix.target }} --workspace --all-features
env:
CC: musl-gcc
CXX: g++
Expand All @@ -86,19 +86,18 @@ jobs:
with:
command: test
toolchain: ${{ matrix.toolchain }}
args: --target ${{ matrix.target }} --workspace
args: --target ${{ matrix.target }} --workspace --all-features
env:
CC: musl-gcc
CXX: g++

# If wasm, then we test only the main module and cloudevents-sdk-reqwest
- uses: actions-rs/cargo@v1
name: "Build"
if: matrix.target == 'wasm32-unknown-unknown'
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --target wasm32-unknown-unknown --package cloudevents-sdk --package cloudevents-sdk-reqwest
args: --target wasm32-unknown-unknown --features cloudevents-reqwest

# Build examples
- uses: actions-rs/cargo@v1
Expand Down
29 changes: 28 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ categories = ["web-programming", "encoding", "data-structures"]
[lib]
name = "cloudevents"

[features]
cloudevents-actix = ["actix-web", "async-trait", "lazy_static", "bytes", "futures"]
cloudevents-reqwest = ["reqwest", "async-trait", "lazy_static", "bytes"]
cloudevents-rdkafka = ["rdkafka", "lazy_static", "bytes"]
cloudevents-warp = ["warp", "lazy_static", "bytes", "http", "hyper"]

[dependencies]
serde = { version = "^1.0", features = ["derive"] }
serde_json = "^1.0"
Expand All @@ -26,6 +32,18 @@ url = { version = "^2.1", features = ["serde"] }
snafu = "^0.6"
bitflags = "^1.2"

# runtime optional deps
actix-web = { version = "^3", default-features = false, optional = true }
reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls"], optional = true }
rdkafka = { version = "^0.25", features = ["cmake-build"], optional = true }
warp = { version = "^0.3", optional = true }
async-trait = { version = "^0.1.33", optional = true }
lazy_static = { version = "1.4.0", optional = true }
bytes = { version = "^1.0", optional = true }
futures = { version = "^0.3", optional = true }
http = { version = "0.2", optional = true }
hyper = { version = "^0.14", optional = true }

[target."cfg(not(target_arch = \"wasm32\"))".dependencies]
hostname = "^0.3"
uuid = { version = "^0.8", features = ["v4"] }
Expand All @@ -40,13 +58,22 @@ claim = "0.3.1"
version-sync = "^0.9"
serde_yaml = "0.8"

# runtime dev-deps
actix-rt = { version = "^1" }
url = { version = "^2.1", features = ["serde"] }
serde_json = { version = "^1.0" }
chrono = { version = "^0.4", features = ["serde"] }
mockito = "0.25.1"
tokio = { version = "^1.0", features = ["full"] }
mime = "0.3"

[workspace]
members = [
".",
"cloudevents-sdk-actix-web",
"cloudevents-sdk-reqwest",
"cloudevents-sdk-rdkafka",
"cloudevents-sdk-warp"
"cloudevents-sdk-warp",
]
exclude = [
"example-projects/actix-web-example",
Expand Down
2 changes: 1 addition & 1 deletion cloudevents-sdk-actix-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ cloudevents-sdk = { version = "0.3.0", path = ".." }
actix-web = { version = "^3", default-features = false }
async-trait = "^0.1.33"
lazy_static = "1.4.0"
bytes = "^0.5"
bytes = "^1.0"
futures = "^0.3"

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion cloudevents-sdk-rdkafka/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ rdkafka = { version = "^0.25", features = ["cmake-build"] }
url = { version = "^2.1" }
serde_json = "^1.0"
chrono = { version = "^0.4", features = ["serde"] }
futures = "0.3.5"
futures = "^0.3"
version-sync = "^0.9"
3 changes: 1 addition & 2 deletions example-projects/actix-web-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ authors = ["Francesco Guardiani <[email protected]>"]
edition = "2018"

[dependencies]
cloudevents-sdk = { path = "../.." }
cloudevents-sdk-actix-web = { path = "../../cloudevents-sdk-actix-web" }
cloudevents-sdk = { path = "../..", features = ["cloudevents-actix"] }
actix-web = "^3"
actix-cors = "^0.5"
lazy_static = "1.4.0"
Expand Down
2 changes: 1 addition & 1 deletion example-projects/actix-web-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use actix_web::{get, post, web, App, HttpRequest, HttpResponse, HttpServer};
use cloudevents::actix::{HttpRequestExt, HttpResponseBuilderExt};
use cloudevents::{EventBuilder, EventBuilderV10};
use cloudevents_sdk_actix_web::{HttpResponseBuilderExt, HttpRequestExt};
use serde_json::json;

#[post("/")]
Expand Down
3 changes: 1 addition & 2 deletions example-projects/rdkafka-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ edition = "2018"

[dependencies]
async-trait = "^0.1.33"
cloudevents-sdk = { path = "../.." }
cloudevents-sdk-rdkafka = { path = "../../cloudevents-sdk-rdkafka" }
cloudevents-sdk = { path = "../..", features = ["cloudevents-rdkafka"] }
lazy_static = "1.4.0"
bytes = "^1.0"
url = { version = "^2.1", features = ["serde"] }
Expand Down
2 changes: 1 addition & 1 deletion example-projects/rdkafka-example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use futures::StreamExt;
use serde_json::json;

use cloudevents::{EventBuilder, EventBuilderV10};
use cloudevents_sdk_rdkafka::{FutureRecordExt, MessageExt, MessageRecord};
use cloudevents::rdkafka::{FutureRecordExt, MessageExt, MessageRecord};

use rdkafka::config::{ClientConfig, RDKafkaLogLevel};
use rdkafka::consumer::stream_consumer::StreamConsumer;
Expand Down
3 changes: 1 addition & 2 deletions example-projects/reqwest-wasm-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ crate-type = ["cdylib"]

[dependencies]
reqwest = "^0.11"
cloudevents-sdk = { path = "../.." }
cloudevents-sdk-reqwest = { path = "../../cloudevents-sdk-reqwest" }
cloudevents-sdk = { path = "../..", features = ["cloudevents-reqwest"] }
url = { version = "^2.1" }
web-sys = { version = "0.3.39", features = ["Window", "Location"] }
wasm-bindgen-futures = "0.4.12"
Expand Down
2 changes: 1 addition & 1 deletion example-projects/reqwest-wasm-example/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cloudevents::reqwest::RequestBuilderExt;
use cloudevents::{EventBuilder, EventBuilderV10};
use cloudevents_sdk_reqwest::RequestBuilderExt;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
Expand Down
3 changes: 1 addition & 2 deletions example-projects/warp-example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ categories = ["web-programming", "encoding"]
license-file = "../LICENSE"

[dependencies]
cloudevents-sdk = { path = "../.." }
cloudevents-sdk-warp = { path = "../../cloudevents-sdk-warp"}
cloudevents-sdk = { path = "../..", features = ["cloudevents-warp"] }
warp = "^0.3"
tokio = { version = "^1.0", features = ["full"] }

Expand Down
2 changes: 1 addition & 1 deletion example-projects/warp-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cloudevents_sdk_warp::{filter, reply};
use cloudevents::warp::{filter, reply};
use warp::Filter;

#[tokio::main]
Expand Down
68 changes: 68 additions & 0 deletions src/actix/headers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::event::SpecVersion;
use actix_web::http::header;
use actix_web::http::{HeaderName, HeaderValue};
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::str::FromStr;

macro_rules! unwrap_optional_header {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but maybe for future refactorings: a lot of these macros are copy paste, because the APIs are practically the same even if their names are different, so it would be nice to find a way to unify them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #146

($headers:expr, $name:expr) => {
$headers
.get::<&'static HeaderName>(&$name)
.map(|a| header_value_to_str!(a))
};
}

macro_rules! header_value_to_str {
($header_value:expr) => {
$header_value
.to_str()
.map_err(|e| crate::message::Error::Other {
source: Box::new(e),
})
};
}

macro_rules! str_to_header_value {
($header_value:expr) => {
HeaderValue::from_str($header_value).map_err(|e| crate::message::Error::Other {
source: Box::new(e),
})
};
}

macro_rules! str_name_to_header {
($attribute:expr) => {
HeaderName::from_str($attribute).map_err(|e| crate::message::Error::Other {
source: Box::new(e),
})
};
}

macro_rules! attribute_name_to_header {
($attribute:expr) => {
str_name_to_header!(&["ce-", $attribute].concat())
};
}

fn attributes_to_headers(
it: impl Iterator<Item = &'static str>,
) -> HashMap<&'static str, HeaderName> {
it.map(|s| {
if s == "datacontenttype" {
(s, header::CONTENT_TYPE)
} else {
(s, attribute_name_to_header!(s).unwrap())
}
})
.collect()
}

lazy_static! {
pub(crate) static ref ATTRIBUTES_TO_HEADERS: HashMap<&'static str, HeaderName> =
attributes_to_headers(SpecVersion::all_attribute_names());
pub(crate) static ref SPEC_VERSION_HEADER: HeaderName =
HeaderName::from_static("ce-specversion");
pub(crate) static ref CLOUDEVENTS_JSON_HEADER: HeaderValue =
HeaderValue::from_static("application/cloudevents+json");
}
54 changes: 54 additions & 0 deletions src/actix/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! This module integrates the [cloudevents-sdk](https://docs.rs/cloudevents-sdk) with [Actix web](https://docs.rs/actix-web/) to easily send and receive CloudEvents.
//!
//! To deserialize an HTTP request as CloudEvent:
//!
//! ```
//! use cloudevents::actix::HttpRequestExt;
//! use actix_web::{HttpRequest, web, post};
//!
//! #[post("/")]
//! async fn post_event(req: HttpRequest, payload: web::Payload) -> Result<String, actix_web::Error> {
//! let event = req.to_event(payload).await?;
//! println!("Received Event: {:?}", event);
//! Ok(format!("{:?}", event))
//! }
//! ```
//!
//! To serialize a CloudEvent to an HTTP response:
//!
//! ```
//! use cloudevents::actix::HttpResponseBuilderExt;
//! use actix_web::{HttpRequest, web, get, HttpResponse};
//! use cloudevents::{EventBuilderV10, EventBuilder};
//! use serde_json::json;
//!
//! #[get("/")]
//! async fn get_event() -> Result<HttpResponse, actix_web::Error> {
//! Ok(HttpResponse::Ok()
//! .event(
//! EventBuilderV10::new()
//! .id("0001")
//! .ty("example.test")
//! .source("http://localhost/")
//! .data("application/json", json!({"hello": "world"}))
//! .build()
//! .expect("No error while building the event"),
//! )
//! .await?
//! )
//! }
//! ```

#![deny(broken_intra_doc_links)]

#[macro_use]
mod headers;
mod server_request;
mod server_response;

pub use server_request::request_to_event;
pub use server_request::HttpRequestDeserializer;
pub use server_request::HttpRequestExt;
pub use server_response::event_to_response;
pub use server_response::HttpResponseBuilderExt;
pub use server_response::HttpResponseSerializer;
Loading