Skip to content

Commit dc81cf6

Browse files
Merge pull request #132 from jcrossley3/actix-impls
Implement actix-web FromRequest and Responder
2 parents 1a9d0d4 + d458116 commit dc81cf6

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

example-projects/actix-web-example/src/main.rs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
1-
use actix_web::{get, post, web, App, HttpRequest, HttpResponse, HttpServer};
2-
use cloudevents::actix::{HttpRequestExt, HttpResponseBuilderExt};
3-
use cloudevents::{EventBuilder, EventBuilderV10};
1+
use actix_web::{get, post, App, HttpServer};
2+
use cloudevents::{Event, EventBuilder, EventBuilderV10};
43
use serde_json::json;
54

65
#[post("/")]
7-
async fn post_event(req: HttpRequest, payload: web::Payload) -> Result<String, actix_web::Error> {
8-
let event = req.to_event(payload).await?;
6+
async fn post_event(event: Event) -> Event {
97
println!("Received Event: {:?}", event);
10-
Ok(format!("{:?}", event))
8+
event
119
}
1210

1311
#[get("/")]
14-
async fn get_event() -> Result<HttpResponse, actix_web::Error> {
12+
async fn get_event() -> Event {
1513
let payload = json!({"hello": "world"});
1614

17-
Ok(HttpResponse::Ok()
18-
.event(
19-
EventBuilderV10::new()
20-
.id("0001")
21-
.ty("example.test")
22-
.source("http://localhost/")
23-
.data("application/json", payload)
24-
.extension("someint", "10")
25-
.build()
26-
.unwrap(),
27-
)
28-
.await?)
15+
EventBuilderV10::new()
16+
.id("0001")
17+
.ty("example.test")
18+
.source("http://localhost/")
19+
.data("application/json", payload)
20+
.extension("someint", "10")
21+
.build()
22+
.unwrap()
2923
}
3024

3125
#[actix_web::main]

src/actix/server_request.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use actix_web::http::HeaderName;
99
use actix_web::web::{Bytes, BytesMut};
1010
use actix_web::{web, HttpMessage, HttpRequest};
1111
use async_trait::async_trait;
12-
use futures::StreamExt;
12+
use futures::future::LocalBoxFuture;
13+
use futures::{FutureExt, StreamExt};
1314
use std::convert::TryFrom;
1415

1516
/// Wrapper for [`HttpRequest`] that implements [`MessageDeserializer`] trait.
@@ -112,6 +113,19 @@ pub async fn request_to_event(
112113
.map_err(actix_web::error::ErrorBadRequest)
113114
}
114115

116+
/// So that an actix-web handler may take an Event parameter
117+
impl actix_web::FromRequest for Event {
118+
type Config = ();
119+
type Error = actix_web::Error;
120+
type Future = LocalBoxFuture<'static, std::result::Result<Self, Self::Error>>;
121+
122+
fn from_request(r: &HttpRequest, p: &mut actix_web::dev::Payload) -> Self::Future {
123+
let payload = web::Payload(p.take());
124+
let request = r.to_owned();
125+
async move { request_to_event(&request, payload).await }.boxed_local()
126+
}
127+
}
128+
115129
/// Extention Trait for [`HttpRequest`] which acts as a wrapper for the function [`request_to_event()`].
116130
///
117131
/// This trait is sealed and cannot be implemented for types outside of this crate.

src/actix/server_response.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ use crate::message::{
55
};
66
use crate::Event;
77
use actix_web::dev::HttpResponseBuilder;
8-
use actix_web::http::{HeaderName, HeaderValue};
8+
use actix_web::http::{HeaderName, HeaderValue, StatusCode};
99
use actix_web::HttpResponse;
1010
use async_trait::async_trait;
11+
use futures::future::LocalBoxFuture;
12+
use futures::FutureExt;
1113
use std::str::FromStr;
1214

1315
/// Wrapper for [`HttpResponseBuilder`] that implements [`StructuredSerializer`] and [`BinarySerializer`].
@@ -76,6 +78,16 @@ pub async fn event_to_response(
7678
.map_err(actix_web::error::ErrorBadRequest)
7779
}
7880

81+
/// So that an actix-web handler may return an Event
82+
impl actix_web::Responder for Event {
83+
type Error = actix_web::Error;
84+
type Future = LocalBoxFuture<'static, std::result::Result<HttpResponse, Self::Error>>;
85+
86+
fn respond_to(self, _: &actix_web::HttpRequest) -> Self::Future {
87+
async { HttpResponse::build(StatusCode::OK).event(self).await }.boxed_local()
88+
}
89+
}
90+
7991
/// Extension Trait for [`HttpResponseBuilder`] which acts as a wrapper for the function [`event_to_response()`].
8092
///
8193
/// This trait is sealed and cannot be implemented for types outside of this crate.

0 commit comments

Comments
 (0)