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}