seanmonstar / warp

A super-easy, composable, web server framework for warp speeds.
https://seanmonstar.com/post/176530511587/warp
MIT License
9.58k stars 719 forks source link

Return non-opaque type from `sse::json`, `sse::event`, etc. #643

Open jhpratt opened 4 years ago

jhpratt commented 4 years ago

I am currently doing

match event {
    Event::Created(event) => Ok((sse::event("create"), sse::json(event))),
    Event::Updated(event) => Ok((sse::event("update"), sse::json(event))),
    Event::Deleted(event) => Ok((sse::event("delete"), sse::json(event))),
}

where Event is defined as

enum Event<C, U, D> {
    Created(C),
    Updated(U),
    Deleted(D),
}

This allows me to merge three streams into one, using a single, known type (Event). I am then using the first block to actually create the server-sent events, which are then streamed in an endpoint. When trying to compile this, I receive an error.

(equivalent of first code block)
    | |_________- `match` arms have incompatible types
    | 
   ::: /home/jhpratt/.cargo/registry/src/github.com-1ecc6299db9ec823/warp-0.2.3/src/filters/sse.rs:113:30
    |
113 |   pub fn event<T>(event: T) -> impl ServerSentEvent
    |                                -------------------- one of the found opaque types
...
221 |   pub fn json<T>(data: T) -> impl ServerSentEvent
    |                              -------------------- one of the found opaque types
    |
    = note: expected type `std::result::Result<(impl warp::filters::sse::ServerSentEvent, impl warp::filters::sse::ServerSentEvent), _>` (type parameter `C`)
               found enum `std::result::Result<(impl warp::filters::sse::ServerSentEvent, impl warp::filters::sse::ServerSentEvent), _>` (type parameter `U`)

The issue is clearly that warp is returning impl ServerSentEvent, which the compiler considers to be a unique type. A quick look at the source code as indicated shows that fn json() returns a parameterized SseJson, as is the case with other methods. I believe it would be feasible to serialize the data immediately, storing the resulting String in an unparameterized struct. This would consequently allow the return of a non-opaque type, eliminating the current necessity to use Either in a number of cases like this.

seanmonstar commented 4 years ago

Yea, I've been meaning for the sse module to be redesigned to return simple structs. I've written that up in #645.

jhpratt commented 4 years ago

Sounds good; I'll leave this open as a sub-feature. Once I finish up my project and have some free time, I'll see what I can do to contribute.