Files
voprf-vx/src/tests/parser.rs
T

115 lines
3.4 KiB
Rust

// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// This source code is dual-licensed under either the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree or the Apache
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree. You may select, at your option, one of the above-listed
// licenses.
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use alloc::{format, vec};
pub(crate) fn rfc_to_json(input: &str) -> String {
format!("{{\n{}\n}}", parse_ciphersuites(input))
}
fn parse_ciphersuites(input: &str) -> String {
let re = regex::Regex::new(r"\nA\.\d\. {2}(?P<ciphersuite>.+?)\n\n").unwrap();
let mut ciphersuites = vec![];
let chunks: Vec<&str> = re.split(input).collect();
let mut count = 1;
for caps in re.captures_iter(input) {
let ciphersuite = format!(
"\"{}\": {{ {} }}",
&caps["ciphersuite"],
parse_modes(chunks[count])
);
ciphersuites.push(ciphersuite);
count += 1;
}
ciphersuites.join(",\n")
}
fn parse_modes(input: &str) -> String {
let re = regex::Regex::new(r"A\.\d.\d\. {2}(?P<mode>.*?) Mode").unwrap();
let mut modes = vec![];
let chunks: Vec<&str> = re.split(input).collect();
let mut count = 1;
for caps in re.captures_iter(input) {
let mode = format!(
"\"{}\": [\n {} \n]",
&caps["mode"],
parse_vectors(chunks[count])
);
modes.push(mode);
count += 1;
}
modes.join(",\n")
}
fn parse_vectors(input: &str) -> String {
let re = regex::Regex::new(r"A\.\d.\d\.\d\. {2}Test Vector.*+\n").unwrap();
let mut vectors = vec![];
let chunks: Vec<&str> = re.split(input).collect();
let init_params = parse_params(chunks[0]);
let mut count = 1;
for _ in re.captures_iter(input) {
let params = format!("{{\n{},\n{}\n}}", init_params, parse_params(chunks[count]));
vectors.push(params);
count += 1;
}
vectors.join(",\n")
}
fn parse_params(input: &str) -> String {
let mut params = vec![];
let mut param = String::new();
let mut lines = input.lines();
loop {
match lines.next() {
None => {
// Clear out any existing string and flush to params
param += "\"";
params.push(param);
return params.join(",\n");
}
Some(line) => {
// If line contains =, then
if line.contains('=') {
// Clear out any existing string and flush to params
if !param.is_empty() {
param += "\"";
params.push(param);
}
let mut iter = line.split('=');
let key = iter.next().unwrap().split_whitespace().next().unwrap();
let val = iter.next().unwrap().split_whitespace().next().unwrap();
param = format!(" \"{key}\": \"{val}");
} else {
let s = line.trim().to_string();
if s.contains('~') || s.contains('#') {
// Ignore comment lines
continue;
}
if !s.is_empty() {
param += &s;
}
}
}
}
}
}