Coder Social home page Coder Social logo

Comments (16)

seanmonstar avatar seanmonstar commented on May 5, 2024 2

I do think it's probably best to change the current Either to be more like frunk's Coprod type, but figuring out the nicest way to do that may take some time (and be brutal to name).

I have wanted at times to be able to sort of "unify" over an Either, when I don't care about which exact case it was, and they are all the same type. Something like the either crate's into_inner(). It could be possible to come up with a trait that's implemented over Either<T, T> that does this, and then it could be used in user code like this:

let path_id = warp::path::param::<u64>();
let header_id = warp::header::<u64>("x-todo-id");

path_id
    .or(header_id)
    .map(handle_id);

// naming is hard
fn handle_id(id: impl EitherUnify<u64>) {
    // ...
}

An alternative is to add some unify or either combinator on Filter that does this for you...

from warp.

davidbarsky avatar davidbarsky commented on May 5, 2024

Adding a small note—I'm writing a generator for Twirp. It'd be pretty nice to be able to write standalone, reusable filters that accept either application/json or application/protobuf, but the or combinator changes the return type of the filter (I'm currently using Hyper directly).

On an aside, is there any reasonable way to hide the Self::Extract tuple as seen here?

(This problem, of course, would go away if Rust had anonymous sum types.)

from warp.

seanmonstar avatar seanmonstar commented on May 5, 2024

I believe with trait specialization, single value extractions can be just T, instead of (T,).

from warp.

davidbarsky avatar davidbarsky commented on May 5, 2024

Ah, gotcha—thank you for clarifying! I suppose specialization would be a better solution in this case than anon. sum types.

from warp.

davidbarsky avatar davidbarsky commented on May 5, 2024

I do think it's probably best to change the current Either to be more like frunk's Coprod type, but figuring out the nicest way to do that may take some time (and be brutal to name).

Yeah, that's fair. It's kinda challenging and exposing Coproduct directly seems... not right?

I have wanted at times to be able to sort of "unify" over an Either, when I don't care about which exact case it was, and they are all the same type. Something like the either crate's into_inner(). It could be possible to come up with a trait that's implemented over Either<T, T> that does this, and then it could be used in user code like this: [code omitted]:

Oh, I like that API a lot! To be clear, if a String and a u64 is extracted, the type of EitherUnify<_> would be impl EitherUnify<String, u64>?

from warp.

seanmonstar avatar seanmonstar commented on May 5, 2024

To be clear, if a String and a u64 is extracted, the type of EitherUnify<_> would be impl EitherUnify<String, u64>?

Oh... No, I had meant specifically when all the types in the Either are the same. So, Either<u64, u64> could be unified to a single u64. If they are different types, then it sounds like you need to match on the Either, right?

from warp.

davidbarsky avatar davidbarsky commented on May 5, 2024

Oh... No, I had meant specifically when all the types in the Either are the same.

I got that part! I can see how Either<u64, u64> can be unified to a single u64. I phrased my followup question poorly—namely, I dropped the tuple in impl EitherUnify<(String, u64)>, trying to write pseudocode that extracts both a string and a u64. I believe specialization would cover this use-case better (hence me commenting here).

I'm sorry if I'm not making sense—I've got too many meetings that are melting my brain.

from warp.

seanmonstar avatar seanmonstar commented on May 5, 2024

Ah, yes, it should, since it'd work for any T, as long as both sides of Either are the same T.

So, for now, I added a Filter::unify() combinator, which will allow anyone to convert to the inner T when using things like or to combine 2 filters that provide the same type.

from warp.

Benjamin-L avatar Benjamin-L commented on May 5, 2024

I'm not sure whether this is the right approach here, but I'm trying to do something like this:

fn render<T>(template: T) -> impl warp::Reply {
    match template.render() {
        Ok(html) => Either::Left(warp::reply::html(html)),
        Err(err) => {
            error!("template rendering failed: {} (for {:#?})", err, template);
            Either::Right(warp::http::StatusCode::INTERNAL_SERVER_ERROR)
    }
}

Since Either isn't exposed, there's no good way to return two different types of Reply from the same function. Is there another approach I should take here, or is waiting for Either the way to go?

from warp.

Benjamin-L avatar Benjamin-L commented on May 5, 2024

Another thing I just thought of, is there any reason not to just use the either crate for this?

from warp.

remexre avatar remexre commented on May 5, 2024

I'm encountering a similar situation; I'd be strongly in favor of either using the either crate's Either type or just using frunk's Coproduct. (If frunk is chosen, the Hlist in src/generic.rs could be nixed too.)

I've got a branch here using the either crate if you need this now, though I'd prefer warp to lean on frunk more heavily instead.

from warp.

Benjamin-L avatar Benjamin-L commented on May 5, 2024

I'm not sure this issue is the right place to mention or discuss this, but in my fairly limited experience using warp, it seems like extensibility is really hurt by the fact that many of the types or traits needed to write things are private. Because you don't have access to many of the parts that make the built in parts of warp function, extending it in a composable way is very hacky.

from warp.

remexre avatar remexre commented on May 5, 2024

@seanmonstar would a PR to frunkify Either be accepted?

This'd essentially just change anything using Either<A, B> to use Coprod!(A, B) instead for now, but it'd be nice to see .or() use .embed() to make most cases of .unify() unnecessary. That'd be a separate PR though, and a very breaking change.

from warp.

seanmonstar avatar seanmonstar commented on May 5, 2024

I had initially thought that if nested enums were used such that the final type were uninhabitable, Rust could optimize the layout to not need space for all the nested tags. I was wrong.

So, maybe, instead there could be something like the Tuple/HList stuff but as a set of enums, like Either2, Either3, etc. Then, combining filters with or could convert an Either2 into an Either3... I haven't tried this out in practice though.

from warp.

remexre avatar remexre commented on May 5, 2024

Eh....... that seems a lot grosser; I'd honestly rather wait to see language support for "first-class" anonymous sums instead. RFC1154 got closed for prioritization reasons; I might try a revival of it as my first RFC after #35121/RFC1216 lands.

from warp.

remexre avatar remexre commented on May 5, 2024

Would a PR of https://github.com/remexre/warp/tree/either-crate be accepted for 0.2, with the change to first-class enums (or Coproduct if optimized tags happen first) being pushed off to a later breaking release?

from warp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.