use crate::ir::{BufferDecl, DataType, Expr, Node, Program};
use crate::ops::{OpSpec, BYTES_TO_BYTES_INPUTS};
pub const WGSL: &str = concat!(
include_str!("../wgsl_byte_primitives/bytes.wgsl"),
"\n",
include_str!("wgsl/utf8_validate.wgsl"),
);
pub const BOOL_OUTPUTS: &[DataType] = &[DataType::Bool];
impl Utf8Validate {
pub const SPEC: OpSpec = OpSpec::composition(
"decode.utf8_validate",
BYTES_TO_BYTES_INPUTS,
BOOL_OUTPUTS,
LAWS,
Self::program,
);
#[must_use]
pub fn program() -> Program {
Program::new(
vec![
BufferDecl::read("input", 0, DataType::Bytes),
BufferDecl::output("out", 1, DataType::Bool),
],
[1, 1, 1],
vec![Node::if_then(
Expr::lt(Expr::u32(0), Expr::buf_len("out")),
vec![Node::store("out", Expr::u32(0), Expr::bool(true))],
)],
)
}
}
pub const LAWS: &[crate::ops::AlgebraicLaw] = &[];
#[must_use]
pub fn utf8_validate(input: &[u8]) -> bool {
core::str::from_utf8(input).is_ok()
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Utf8Validate;
#[test]
pub fn committed_kats_match_cpu_reference() -> Result<(), String> {
crate::ops::fixtures::run_committed_kats(
include_str!("../fixtures/reference-vectors.toml"),
|case| {
if case.op.as_deref() != Some("utf8_validate") {
return Ok(());
}
let input = crate::ops::fixtures::hex_to_bytes(
case.input_hex.as_ref().ok_or("Fix: missing input_hex")?,
)?;
let expected = crate::ops::fixtures::hex_to_bytes(
case.expected_output_hex
.as_ref()
.ok_or("Fix: missing expected_output_hex")?,
)?;
assert_eq!(expected.len(), 1);
assert_eq!(utf8_validate(&input), expected[0] == 1);
Ok(())
},
)
}