Skip to main content

mockforge_openapi/
response_rewriter.rs

1//! Response-mutation hooks the OpenAPI router calls on each generated body.
2//!
3//! 1. [`ResponseRewriter`] expands template tokens like `{{uuid}}`.
4//! 2. [`OverrideHook`] applies user-supplied override rules.
5//!
6//! Both engines live in `mockforge-core`. The router dispatches through
7//! these traits so `mockforge-openapi` does not depend on core's templating
8//! and conditions graph. Core supplies the implementations
9//! (`mockforge_core::openapi_rewriter::CoreResponseRewriter` and
10//! `mockforge_core::SharedOverrides`).
11
12use axum::http::HeaderMap;
13use serde_json::Value;
14
15/// Hook for template token expansion, called only when expansion is enabled
16/// for the current context.
17pub trait ResponseRewriter: Send + Sync {
18    /// Expand template tokens (e.g. `{{uuid}}`, `{{now}}`) in-place inside
19    /// the response body.
20    fn expand_tokens(&self, body: &mut Value);
21}
22
23/// The request an override rule is evaluated against
24#[derive(Debug, Clone, Copy)]
25pub struct OverrideRequest<'a> {
26    /// HTTP method, uppercase
27    pub method: &'a str,
28    /// The OpenAPI path template, e.g. `/users/{id}`
29    pub path_template: &'a str,
30    /// The operation's `operationId`, or empty when the spec has none
31    pub operation_id: &'a str,
32    /// The operation's OpenAPI tags followed by its `operationId`
33    pub tags: &'a [String],
34    /// Request headers
35    pub headers: &'a HeaderMap,
36    /// Raw query string, without the leading `?`
37    pub query: Option<&'a str>,
38    /// Raw request body
39    pub body: &'a [u8],
40}
41
42/// Hook that applies override rules to a generated response body
43pub trait OverrideHook: Send + Sync {
44    /// Patch `body` in place with every rule that matches `request`
45    fn apply(&self, request: &OverrideRequest<'_>, body: &mut Value);
46}