hen 0.16.0

Run protocol-aware API request collections from the command line or through MCP.
Documentation
use crate::request::{RedactionRules, validate_redaction_body_path};

use super::Rule;

pub(super) fn apply_redaction_directive(
    rules: &mut RedactionRules,
    pair: pest::iterators::Pair<Rule>,
) -> Result<(), pest::error::Error<Rule>> {
    let rule = pair.as_rule();
    let span = pair.as_span();
    let raw_value = pair
        .into_inner()
        .next()
        .expect("redaction directives should include a value")
        .as_str()
        .trim()
        .to_string();

    let result = match rule {
        Rule::redact_header_directive => rules.add_header_name(&raw_value),
        Rule::redact_capture_directive => rules.add_capture_name(&raw_value),
        Rule::redact_body_directive => {
            if let Err(err) = validate_redaction_body_path(&raw_value) {
                return Err(custom_error(err.to_string(), span));
            }
            rules.add_body_path(&raw_value)
        }
        _ => unreachable!("unexpected redaction directive: {:?}", rule),
    };

    result.map_err(|message| custom_error(message, span))
}

pub(super) fn reject_misplaced_redaction_directive(
    raw: &str,
    span: pest::Span<'_>,
) -> Result<(), pest::error::Error<Rule>> {
    if looks_like_redaction_directive(raw) {
        return Err(custom_error(
            "redaction directives must appear before the first ---".to_string(),
            span,
        ));
    }

    Ok(())
}

fn looks_like_redaction_directive(raw: &str) -> bool {
    let trimmed = raw.trim_start();
    ["redact_header", "redact_capture", "redact_body"]
        .iter()
        .any(|prefix| {
            trimmed
                .strip_prefix(prefix)
                .map(|remainder| remainder.trim_start().starts_with('='))
                .unwrap_or(false)
        })
}

fn custom_error(message: String, span: pest::Span<'_>) -> pest::error::Error<Rule> {
    pest::error::Error::new_from_span(
        pest::error::ErrorVariant::CustomError { message },
        span,
    )
}