Skip to main content

vane_core/
metadata.rs

1use crate::error::Error;
2use crate::fetch::{FetchKind, FetchOutputModes, FetchPhase};
3use crate::middleware::MiddlewareKind;
4
5pub struct MiddlewareMetadata {
6	pub kind: MiddlewareKind,
7	pub stateless: bool,
8	pub needs_body: bool,
9	pub validate_args: fn(&serde_json::Value) -> Result<(), Error>,
10}
11
12pub trait MiddlewareMetadataProvider {
13	fn get(&self, name: &str) -> Option<MiddlewareMetadata>;
14}
15
16pub struct FetchMetadata {
17	pub kind: FetchKind,
18	pub phase: FetchPhase,
19	pub output_modes: FetchOutputModes,
20	pub validate_args: fn(&serde_json::Value) -> Result<(), Error>,
21}
22
23pub trait FetchMetadataProvider {
24	fn get(&self, kind: FetchKind) -> Option<FetchMetadata>;
25}
26
27#[cfg(test)]
28mod tests {
29	use serde_json::{Value, json};
30
31	use super::*;
32	use crate::error::Error;
33
34	fn reject_null_accept_object(v: &Value) -> Result<(), Error> {
35		match v {
36			Value::Object(_) => Ok(()),
37			_ => Err(Error::compile("expected object")),
38		}
39	}
40
41	struct StaticMwProvider;
42	impl MiddlewareMetadataProvider for StaticMwProvider {
43		fn get(&self, name: &str) -> Option<MiddlewareMetadata> {
44			if name == "rate_limit" {
45				Some(MiddlewareMetadata {
46					kind: MiddlewareKind::L7Request,
47					stateless: false,
48					needs_body: false,
49					validate_args: reject_null_accept_object,
50				})
51			} else {
52				None
53			}
54		}
55	}
56
57	struct StaticFetchProvider;
58	impl FetchMetadataProvider for StaticFetchProvider {
59		fn get(&self, kind: FetchKind) -> Option<FetchMetadata> {
60			if kind == FetchKind::HttpProxy {
61				Some(FetchMetadata {
62					kind: FetchKind::HttpProxy,
63					phase: FetchPhase::L7,
64					output_modes: FetchOutputModes { response: true, tunnel: false },
65					validate_args: reject_null_accept_object,
66				})
67			} else {
68				None
69			}
70		}
71	}
72
73	#[test]
74	fn middleware_provider_returns_known_record_and_none_for_unknown() {
75		let p = StaticMwProvider;
76		let meta = p.get("rate_limit").expect("known entry");
77		assert_eq!(meta.kind, MiddlewareKind::L7Request);
78		assert!(!meta.stateless);
79		assert!(!meta.needs_body);
80		assert!(p.get("no_such_middleware").is_none());
81	}
82
83	#[test]
84	fn middleware_validate_args_fn_pointer_dispatches() {
85		let p = StaticMwProvider;
86		let meta = p.get("rate_limit").expect("known entry");
87		assert!((meta.validate_args)(&Value::Null).is_err());
88		assert!((meta.validate_args)(&json!({ "rate": 100 })).is_ok());
89	}
90
91	#[test]
92	fn middleware_provider_is_object_safe() {
93		let p: &dyn MiddlewareMetadataProvider = &StaticMwProvider;
94		assert!(p.get("rate_limit").is_some());
95		assert!(p.get("unknown").is_none());
96	}
97
98	#[test]
99	fn fetch_provider_returns_known_kind_and_none_for_unknown() {
100		let p = StaticFetchProvider;
101		let meta = p.get(FetchKind::HttpProxy).expect("known kind");
102		assert_eq!(meta.kind, FetchKind::HttpProxy);
103		assert_eq!(meta.phase, FetchPhase::L7);
104		assert_eq!(meta.output_modes, FetchOutputModes { response: true, tunnel: false });
105		assert!(p.get(FetchKind::L4Forward).is_none());
106	}
107
108	#[test]
109	fn fetch_validate_args_fn_pointer_dispatches() {
110		let p = StaticFetchProvider;
111		let meta = p.get(FetchKind::HttpProxy).expect("known kind");
112		assert!((meta.validate_args)(&Value::Null).is_err());
113		assert!((meta.validate_args)(&json!({ "upstream": "127.0.0.1:80" })).is_ok());
114	}
115
116	#[test]
117	fn fetch_provider_is_object_safe() {
118		let p: &dyn FetchMetadataProvider = &StaticFetchProvider;
119		assert!(p.get(FetchKind::HttpProxy).is_some());
120		assert!(p.get(FetchKind::WebSocketUpgrade).is_none());
121	}
122}