use crate::{ElicitCommunicator, ElicitResult, Elicitation, Generator, Prompt};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Validator;
impl Validator {
pub fn is_utf8(&self, bytes: &[u8]) -> bool {
std::str::from_utf8(bytes).is_ok()
}
pub fn is_non_empty(&self, s: &str) -> bool {
!s.is_empty()
}
pub fn is_in_range<T: PartialOrd>(&self, value: T, min: T, max: T) -> bool {
value >= min && value <= max
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Formatter;
impl Formatter {
pub fn uppercase(&self, s: &str) -> String {
s.to_uppercase()
}
pub fn lowercase(&self, s: &str) -> String {
s.to_lowercase()
}
pub fn trim(&self, s: &str) -> String {
s.trim().to_string()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Parser;
impl Parser {
pub fn parse_int(&self, s: &str) -> Result<i64, std::num::ParseIntError> {
s.parse()
}
pub fn parse_float(&self, s: &str) -> Result<f64, std::num::ParseFloatError> {
s.parse()
}
pub fn parse_bool(&self, s: &str) -> Result<bool, std::str::ParseBoolError> {
s.parse()
}
}
impl Generator for Validator {
type Target = Self;
fn generate(&self) -> Self::Target {
Validator
}
}
impl Generator for Formatter {
type Target = Self;
fn generate(&self) -> Self::Target {
Formatter
}
}
impl Generator for Parser {
type Target = Self;
fn generate(&self) -> Self::Target {
Parser
}
}
crate::default_style!(Validator => ValidatorStyle);
crate::default_style!(Formatter => FormatterStyle);
crate::default_style!(Parser => ParserStyle);
impl Prompt for Validator {
fn prompt() -> Option<&'static str> {
Some("Create a Validator instance (unit struct - only one value)")
}
}
impl Elicitation for Validator {
type Style = ValidatorStyle;
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
tracing::debug!("Eliciting Validator (unit struct)");
Ok(Validator)
}
fn kani_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::kani_unit_struct("Validator")
}
fn verus_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::verus_unit_struct("Validator")
}
fn creusot_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::creusot_unit_struct("Validator")
}
}
impl Prompt for Formatter {
fn prompt() -> Option<&'static str> {
Some("Create a Formatter instance (unit struct - only one value)")
}
}
impl Elicitation for Formatter {
type Style = FormatterStyle;
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
tracing::debug!("Eliciting Formatter (unit struct)");
Ok(Formatter)
}
fn kani_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::kani_unit_struct("Formatter")
}
fn verus_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::verus_unit_struct("Formatter")
}
fn creusot_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::creusot_unit_struct("Formatter")
}
}
impl Prompt for Parser {
fn prompt() -> Option<&'static str> {
Some("Create a Parser instance (unit struct - only one value)")
}
}
impl Elicitation for Parser {
type Style = ParserStyle;
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
tracing::debug!("Eliciting Parser (unit struct)");
Ok(Parser)
}
fn kani_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::kani_unit_struct("Parser")
}
fn verus_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::verus_unit_struct("Parser")
}
fn creusot_proof() -> proc_macro2::TokenStream {
crate::verification::proof_helpers::creusot_unit_struct("Parser")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validator_methods() {
let v = Validator;
assert!(v.is_utf8(b"hello"));
assert!(!v.is_utf8(b"\xFF\xFE"));
assert!(v.is_non_empty("test"));
assert!(!v.is_non_empty(""));
assert!(v.is_in_range(5, 0, 10));
assert!(!v.is_in_range(15, 0, 10));
}
#[test]
fn test_formatter_methods() {
let f = Formatter;
assert_eq!(f.uppercase("hello"), "HELLO");
assert_eq!(f.lowercase("WORLD"), "world");
assert_eq!(f.trim(" test "), "test");
}
#[test]
fn test_parser_methods() {
let p = Parser;
assert_eq!(p.parse_int("42").unwrap(), 42);
let result = p.parse_float("2.5").unwrap();
assert!((result - 2.5_f64).abs() < 0.001);
assert!(p.parse_bool("true").unwrap());
}
#[test]
fn test_generator_trivial() {
let v = Validator;
assert_eq!(v.generate(), Validator);
let f = Formatter;
assert_eq!(f.generate(), Formatter);
let p = Parser;
assert_eq!(p.generate(), Parser);
}
}