use crate::prelude::{Ident, TokenTree};
use crate::{Error, Result};
use std::iter::Peekable;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum DataType {
Enum,
Struct,
}
impl DataType {
pub(crate) fn take(
input: &mut Peekable<impl Iterator<Item = TokenTree>>,
) -> Result<(Self, Ident)> {
if let Some(ident) = super::utils::consume_ident(input) {
let result = match ident.to_string().as_str() {
"struct" => DataType::Struct,
"enum" => DataType::Enum,
_ => return Err(Error::UnknownDataType(ident.span())),
};
if let Some(ident) = super::utils::consume_ident(input) {
return Ok((result, ident));
}
}
Error::wrong_token(input.peek(), "ident")
}
}
#[test]
fn test_datatype_take() {
use crate::token_stream;
fn validate_output_eq(input: &str, expected_dt: DataType, expected_ident: &str) {
let (dt, ident) = DataType::take(&mut token_stream(input)).unwrap_or_else(|e| {
panic!("Could not parse tokenstream {:?}: {:?}", input, e);
});
if dt != expected_dt || ident != expected_ident {
println!("While parsing {:?}", input);
panic!(
"Expected {:?} {:?}, received {:?} {:?}",
dt, ident, expected_dt, expected_ident
);
}
}
assert!(DataType::take(&mut token_stream("enum"))
.unwrap_err()
.is_invalid_rust_syntax());
validate_output_eq("enum Foo", DataType::Enum, "Foo");
validate_output_eq("enum Foo { }", DataType::Enum, "Foo");
validate_output_eq("enum Foo { bar, baz }", DataType::Enum, "Foo");
validate_output_eq("enum Foo<'a, T> { bar, baz }", DataType::Enum, "Foo");
assert!(DataType::take(&mut token_stream("struct"))
.unwrap_err()
.is_invalid_rust_syntax());
validate_output_eq("struct Foo { }", DataType::Struct, "Foo");
validate_output_eq("struct Foo { bar: u32, baz: u32 }", DataType::Struct, "Foo");
validate_output_eq("struct Foo<'a, T> { bar: &'a T }", DataType::Struct, "Foo");
assert!(DataType::take(&mut token_stream("fn foo() {}"))
.unwrap_err()
.is_unknown_data_type());
assert!(DataType::take(&mut token_stream("() {}"))
.unwrap_err()
.is_invalid_rust_syntax());
assert!(DataType::take(&mut token_stream(""))
.unwrap_err()
.is_invalid_rust_syntax());
}