Trying to design a nice API around functions/closures

I need an interface where I take a bunch of functions handling different types and I need to know what type they handle. Note I didn't say "return", because I'd really like to use references, not owned data (for performance, as this actually might be a fairly hot path: I'd love to avoid unneeded allocations here). Still, returning owned data is probably a valid way out if it helps.

In a completely ideal world, I'd have something like:

// free functions or methods, I'm fine either way (I probably don't need closures)
fn handle_i32(&blah) -> i32 { ... }
fn handle_i32_again(&blah) -> i32 { ... } // the types aren't unique
fn handle_str(&blah) -> &str { ... } // this does not borrow from args
fn handle_str_slice(&blah) -> &[str] { ... }

// in a trait impl
const HANDLERS = [
handle_i32.with_name("sample.i32"),
handle_i32_again.with_name("sample.another_i32"),
handle_str.with_name("sample.str"),
handle_str_slice.with_name("sample.str_slice"),
];

with some introspection, letting me know that HANDLERS[0].TYPE_ID == TypeId::Number and HANDLERS[3].TYPE_ID == TypeId::String && HANDLERS[3].IS_LIST == true.

I cannot use the return value for introspection, since I cannot really return references to locals, so more realistically, the handler functions would look like:

fn handle_str_slice(&blah, out: Takes<&[&str]>) {
    out.emit(&["foo", "bar"])
}

(instead of returning a reference, pass it to something that can do the final processing step).

Unfortunately, as I have learned, I cannot handle all this by a trait implemented on FnMut(..., Takes<T>), because there may be multiple implementations.

Is there a way to detect the handled type while keeping the const HANDLERS part as clean as possible? That will be written by the user of my library and I want minimal friction in there. I'm trying to avoid proc macros so the API remains fairly discoverable with an IDE.

Rust doesn't allow function signature overloading if that's what you are looking for. The only flexibility is to define inputs that are generic.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.