1use crate::engine::AssertionResult;
2use anyhow::Result;
3use serde_json::Value;
4use std::collections::HashMap;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
9pub struct PluginContext<'a> {
10 pub response: &'a Value,
11 pub headers: Option<&'a HashMap<String, String>>,
12 pub trailers: Option<&'a HashMap<String, String>>,
13 pub timing: Option<&'a AssertionTiming>,
14}
15
16impl<'a> PluginContext<'a> {
17 pub fn new(response: &'a Value) -> Self {
18 Self {
19 response,
20 headers: None,
21 trailers: None,
22 timing: None,
23 }
24 }
25 pub fn with_headers(mut self, headers: Option<&'a HashMap<String, String>>) -> Self {
26 self.headers = headers;
27 self
28 }
29 pub fn with_trailers(mut self, trailers: Option<&'a HashMap<String, String>>) -> Self {
30 self.trailers = trailers;
31 self
32 }
33 pub fn with_timing(mut self, timing: Option<&'a AssertionTiming>) -> Self {
34 self.timing = timing;
35 self
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
41pub struct AssertionTiming {
42 pub elapsed_ms: u64,
43 pub total_elapsed_ms: u64,
44 pub scope_message_count: usize,
45 pub scope_index: usize,
46}
47
48#[derive(Debug, Clone, PartialEq)]
50pub enum PluginResult {
51 Assertion(AssertionResult),
52 Value(Value),
53}
54
55pub trait PluginApi: Send + Sync {
57 fn execute(&self, args: &[Value], context: &PluginContext) -> Result<PluginResult>;
58}
59
60pub trait PluginRegistry: Send + Sync {
62 fn get_plugin(&self, name: &str) -> Option<Arc<dyn PluginApi>>;
63}
64
65pub struct NoopPluginRegistry;
67
68impl PluginRegistry for NoopPluginRegistry {
69 fn get_plugin(&self, _name: &str) -> Option<Arc<dyn PluginApi>> {
70 None
71 }
72}