a3s-boot 0.1.3

Adapter-first modular Rust web framework for A3S inspired by Nest.js
Documentation
use crate::{BootError, Result};
use percent_encoding::percent_decode_str;

pub(crate) fn decode_percent_encoded(value: &str) -> Result<String> {
    validate_percent_encoding(value)?;
    percent_decode_str(value)
        .decode_utf8()
        .map(|value| value.into_owned())
        .map_err(|err| BootError::BadRequest(err.to_string()))
}

pub(crate) fn validate_percent_encoding(value: &str) -> Result<()> {
    let bytes = value.as_bytes();
    let mut index = 0;

    while index < bytes.len() {
        if bytes[index] == b'%' {
            if index + 2 >= bytes.len()
                || !bytes[index + 1].is_ascii_hexdigit()
                || !bytes[index + 2].is_ascii_hexdigit()
            {
                return Err(BootError::BadRequest(format!(
                    "invalid percent encoding: {value}"
                )));
            }
            index += 3;
        } else {
            index += 1;
        }
    }

    Ok(())
}