mockforge_core/overrides/
models.rs

1//! Override data models and types
2//!
3//! This module defines the core data structures for the override system:
4//! - OverrideRule: Configuration for applying overrides
5//! - OverrideMode: How patches are applied
6//! - PatchOp: Individual patch operations
7//! - Overrides: Container for multiple rules
8
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::collections::HashMap;
12
13/// Configuration for a single override rule
14#[derive(Debug, Clone, Deserialize, Serialize)]
15pub struct OverrideRule {
16    /// Target selectors for matching operations:
17    /// - "operation:opId" - match by operation ID
18    /// - "tag:Tag" - match by OpenAPI tag
19    /// - "regex:pattern" - match path by regex pattern
20    /// - "path:pattern" - match path by literal pattern
21    pub targets: Vec<String>,
22    /// JSON patch operations to apply when this rule matches
23    pub patch: Vec<PatchOp>,
24    /// Optional condition expression (JSONPath/XPath) that must evaluate to true
25    pub when: Option<String>,
26    /// Override mode for applying patches: "replace" (default) or "merge"
27    #[serde(default = "default_mode")]
28    pub mode: OverrideMode,
29    /// Whether to apply post-templating expansion after patching
30    #[serde(default = "default_post_templating")]
31    pub post_templating: bool,
32}
33
34/// Override mode for applying patches
35#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
36pub enum OverrideMode {
37    /// Replace values (default JSON patch behavior)
38    #[serde(rename = "replace")]
39    Replace,
40    /// Merge objects and arrays instead of replacing
41    #[serde(rename = "merge")]
42    Merge,
43}
44
45/// JSON patch operation (RFC 6902 format)
46#[derive(Debug, Clone, Deserialize, Serialize)]
47#[serde(tag = "op")]
48pub enum PatchOp {
49    /// Add a new value at the specified path
50    #[serde(rename = "add")]
51    Add {
52        /// JSON pointer path to add the value
53        path: String,
54        /// Value to add
55        value: Value,
56    },
57    /// Replace the value at the specified path
58    #[serde(rename = "replace")]
59    Replace {
60        /// JSON pointer path to replace
61        path: String,
62        /// New value
63        value: Value,
64    },
65    /// Remove the value at the specified path
66    #[serde(rename = "remove")]
67    Remove {
68        /// JSON pointer path to remove
69        path: String,
70    },
71}
72
73/// Container for override rules with performance optimizations
74#[derive(Debug, Default, Clone, Deserialize, Serialize)]
75pub struct Overrides {
76    /// Loaded override rules to apply to responses
77    pub rules: Vec<OverrideRule>,
78    /// Compiled regex patterns for performance (cached compilation)
79    #[serde(skip)]
80    pub regex_cache: HashMap<String, regex::Regex>,
81}
82
83fn default_mode() -> OverrideMode {
84    OverrideMode::Replace
85}
86
87fn default_post_templating() -> bool {
88    false
89}