//! Test-only helpers for calling generated service traits directly.
//!
//! Production requests are assembled by connectrpc's generated dispatch glue,
//! which owns the request body for the duration of the handler call. Tests
//! and benches that invoke trait methods directly (no HTTP layer) need a
//! [`ServiceRequest`] with no surrounding call frame to borrow from —
//! [`service_request`] provides one by leaking the encoded body, which is
//! acceptable for one-shot test requests but NOT for loops (use an explicit
//! [`OwnedView`] + [`ServiceRequest::from_parts`] two-liner there).

use buffa::HasMessageView;
use buffa::view::{OwnedView, ViewReborrow};
use connectrpc::ServiceRequest;

/// Build a `'static` [`ServiceRequest`] from an owned request message for
/// direct service-trait invocation in tests.
///
/// Encodes `msg` and leaks the backing buffer (a few hundred bytes per call)
/// so the returned request satisfies any handler lifetime.
///
/// # Panics
///
/// Panics if the message fails the encode → view-decode round trip, which
/// cannot happen for well-formed generated types.
#[must_use]
pub fn service_request<Req>(msg: &Req) -> ServiceRequest<'static, Req>
where
    Req: HasMessageView,
    Req::View<'static>: ViewReborrow<Reborrowed<'static> = Req::View<'static>>,
{
    let owned: &'static OwnedView<Req::View<'static>> = Box::leak(Box::new(
        OwnedView::from_owned(msg)
            .expect("well-formed generated message must round-trip encode → view-decode"),
    ));
    ServiceRequest::from_parts(owned.reborrow(), owned.bytes())
}
