Decode payload (rehydrate PII).
(&self, payload: serde_json::Value, context: DecodeContext)
| 268 | |
| 269 | /// Decode payload (rehydrate PII). |
| 270 | pub fn decode(&self, payload: serde_json::Value, context: DecodeContext) -> DecodeResult { |
| 271 | let default_result = DecodeResult { |
| 272 | payload: payload.clone(), |
| 273 | rules_applied_count: 0, |
| 274 | rule_names: Vec::new(), |
| 275 | policy_name: String::new(), |
| 276 | }; |
| 277 | if self.handle.is_null() { |
| 278 | return default_result; |
| 279 | } |
| 280 | let json = match serde_json::to_string(&payload) { |
| 281 | Ok(s) => s, |
| 282 | Err(_) => return default_result, |
| 283 | }; |
| 284 | let c_str = match CString::new(json.as_bytes()) { |
| 285 | Ok(c) => c, |
| 286 | Err(_) => return default_result, |
| 287 | }; |
| 288 | let ctx = match context { |
| 289 | DecodeContext::ToolBoundary => CONTEXT_TOOL_BOUNDARY, |
| 290 | DecodeContext::LlmResponse => CONTEXT_LLM_RESPONSE, |
| 291 | DecodeContext::ManualCall => CONTEXT_MANUAL_CALL, |
| 292 | }; |
| 293 | let out = |
| 294 | unsafe { guardrail_decode(self.handle, c_str.as_ptr(), c_str.as_bytes().len(), ctx) }; |
| 295 | if out.is_null() { |
| 296 | return default_result; |
| 297 | } |
| 298 | let out_slice = unsafe { CStr::from_ptr(out).to_bytes() }; |
| 299 | let out_str = String::from_utf8_lossy(out_slice).into_owned(); |
| 300 | unsafe { guardrail_free(out) }; |
| 301 | parse_decode_result(&out_str) |
| 302 | .or_else(|| parse_decode_result_legacy(&out_str)) |
| 303 | .unwrap_or(default_result) |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | /// Legacy FFI return: raw encoded payload as JSON (old guardrail_encode returned Value serialized). |