In rspc, any type returned from a procedure handler must implement the ResolverOutput trait.
By default, rspc provides an implementation for any type that satisfies the following bounds:
serde::Serializespecta::TypeSend + Sync + 'static
When you return a value (or a Future that resolves to a value), rspc converts it into a ProcedureStream which is then used by the internal execution engine. If your handler returns a Stream, rspc will flatten it into a ProcedureStream automatically.
If you need to return a custom type that doesn't meet the default bounds, you must manually implement ResolverOutput and define how it converts into a ProcedureOutput (via into_procedure_result).
// Standard usage with types that implement Serialize and specta::Type
<Procedure>::builder().query(|_, _: ()| async move {
MyCoolThing("Hello, World!".to_string())
});