use proc_macro2::TokenStream;
use syn::{Attribute, Ident, Local, Token, Visibility};
use crate::ast::node::Pattern;
#[cfg_attr(any(feature = "extra-traits", test), derive(Debug))]
pub struct BindInput {
pub local: Local,
pub input: Ident,
pub _arrow: Token![->],
pub patterns: Pattern,
pub suffix: TokenStream,
}
#[cfg_attr(any(feature = "extra-traits", test), derive(Debug))]
pub struct DefineInput {
pub attrs: Vec<Attribute>,
pub visibility: Visibility,
pub name: Ident,
pub _colon: Token![:],
pub patterns: Pattern,
}
#[cfg(test)]
mod tests {
use crate::codegen::logic::Compiler;
use super::*;
use quote::quote;
use syn::parse2;
#[test]
fn test_parse_valid_input() {
let stream = quote! { let res = (my_tokens -> name: Ident); };
let result: BindInput = parse2(stream).unwrap();
assert_eq!(result.input.to_string(), "my_tokens");
}
#[test]
fn test_parse_complex_patterns() {
let stream = quote! {
let res = (input_stream -> #(x: Ident));
};
let result: BindInput = parse2(stream).unwrap();
assert_eq!(result.input.to_string(), "input_stream");
}
#[test]
fn test_parse_error_missing_arrow() {
let stream = quote! { my_tokens name: Ident };
let result = parse2::<BindInput>(stream);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "expected `let`");
}
#[test]
fn test_parse_error_missing_input() {
let stream = quote! { -> name: Ident };
let result = parse2::<BindInput>(stream);
assert!(result.is_err());
}
#[test]
fn test_to_tokens_structure() {
let mut compiler = Compiler::new();
let stream = quote! { let res = (tokens -> #(val: Ident)); };
let capture_input: BindInput = parse2(stream).unwrap();
let output = compiler.compile_capture_input(&capture_input);
let output_str = output.to_string();
assert!(output_str.contains("struct Output"));
assert!(output_str.contains("| input : :: syn :: parse :: ParseStream |"));
assert!(output_str.contains("-> :: syn :: Result < Output >"));
assert!(output_str.contains(":: syn :: parse :: Parser :: parse2"));
assert!(output_str.contains("(parser , tokens . into ())"));
}
#[test]
fn test_to_tokens_suffix() {
let mut compiler = Compiler::new();
let stream = quote! { let res = (t -> v: Ident)?; };
let capture_input: BindInput = parse2(stream).unwrap();
let output = compiler.compile_capture_input(&capture_input);
let output_str = output.to_string();
assert!(output_str.trim().starts_with("let res ="));
assert!(output_str.trim().ends_with("} ? ;"));
}
#[test]
fn test_generated_logic_contains_initialization() {
let mut compiler = Compiler::new();
let stream = quote! { let res = (t -> #(val?: Ident)); };
let capture_input: BindInput = parse2(stream).unwrap();
let output = compiler.compile_capture_input(&capture_input).to_string();
assert!(output.contains("Option :: None"));
assert!(output.contains(":: std :: result :: Result :: Ok"));
}
}