http_wasm_guest/host/feature.rs
1//! Host feature flags for configuring runtime capabilities.
2//!
3//! Use these flags to enable host-supported functionality such as buffering
4//! request/response bodies or accessing trailers. Combine multiple flags with
5//! bitwise OR and pass the result to `admin::enable`.
6use std::ops::{BitOr, BitOrAssign};
7
8#[allow(non_upper_case_globals, non_snake_case)]
9/// Enables buffering of the entire request body before your handler is invoked.
10///
11/// When enabled, the host reads the full request body into memory and then makes it
12/// available to the guest. This allows multiple reads and supports request body
13/// inspection or mutation workflows that need complete payload access.
14///
15/// Trade-offs:
16/// - Increased memory usage proportional to request size
17/// - Potential latency from buffering large payloads
18///
19/// Use this flag only when your plugin must read or modify the request body.
20pub const BufferRequest: Feature = Feature(1);
21#[allow(non_upper_case_globals, non_snake_case)]
22/// Enables buffering of the entire response body before it is sent.
23///
24/// When enabled, the host collects the full response body so the guest can read and
25/// modify it during response handling. This is required for plugins that rewrite,
26/// filter, or analyze full response payloads.
27///
28/// Trade-offs:
29/// - Increased memory usage proportional to response size
30/// - Potential latency from buffering large payloads
31///
32/// Use this flag only when your plugin needs full response body access.
33pub const BufferResponse: Feature = Feature(2);
34#[allow(non_upper_case_globals, non_snake_case)]
35/// Enables HTTP trailer support for chunked transfer encoding.
36///
37/// When enabled, the guest can access and modify trailer headers that arrive after
38/// the body. Trailers are typically used to convey metadata computed during streaming,
39/// such as checksums or signatures.
40///
41/// Notes:
42/// - Not all hosts or upstream servers support trailers
43/// - Trailers are only applicable to chunked or streaming responses
44pub const Trailers: Feature = Feature(4);
45
46/// Bitflag wrapper used to configure host capabilities.
47///
48/// Combine flags with `|` and pass the result to `admin::enable`.
49#[derive(Debug, PartialEq, Clone, Copy)]
50pub struct Feature(i32);
51
52impl From<Feature> for i32 {
53 fn from(val: Feature) -> Self {
54 val.0
55 }
56}
57
58impl BitOr for Feature {
59 type Output = Feature;
60
61 fn bitor(self, rhs: Self) -> Feature {
62 Feature(self.0 | rhs.0)
63 }
64}
65
66impl BitOrAssign for Feature {
67 fn bitor_assign(&mut self, rhs: Self) {
68 self.0 |= rhs.0;
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn feature_buffer_request() {
78 assert_eq!(BufferRequest.0, 1);
79 }
80
81 #[test]
82 fn feature_buffer_response() {
83 assert_eq!(BufferResponse.0, 2);
84 }
85
86 #[test]
87 fn feature_trailers() {
88 assert_eq!(Trailers.0, 4);
89 }
90
91 #[test]
92 fn feature_combine_with_bitor() {
93 let combined = BufferRequest | BufferResponse;
94 assert_eq!(combined, Feature(3));
95 }
96
97 #[test]
98 fn feature_combine_with_bitorassign() {
99 let mut f = BufferRequest;
100 f |= BufferResponse;
101 assert_eq!(f, Feature(3));
102 }
103
104 #[test]
105 fn feature_combine_all() {
106 let combined = BufferRequest | BufferResponse | Trailers;
107 assert_eq!(combined, Feature(7));
108 }
109
110 #[test]
111 fn feature_debug_output() {
112 let f = Feature(42);
113 let debug_str = format!("{:?}", f);
114 assert!(debug_str.contains("42"));
115 }
116
117 #[test]
118 fn feature_partial_eq() {
119 assert_eq!(Feature(5), Feature(5));
120 assert_ne!(Feature(1), Feature(2));
121 }
122
123 #[test]
124 fn feature_into_i32() {
125 let f = Feature(123);
126 let val: i32 = f.into();
127 assert_eq!(val, 123);
128 }
129}