vin-macros 7.0.0

Procedural macros that power vin
Documentation
use syn::{Ident, parse::Parse, Error, TypePath, Token, token};

pub struct Attr {
	pub result: Option<TypePath>,
	pub error: Option<TypePath>,
}

impl Parse for Attr {
	fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
		if input.is_empty() { return Ok(Self { result: None, error: None }) }

		let mut result = None;
		let mut error = None;

		let mut read_arg = || {
			let ident = input.parse::<Ident>()?;
			input.parse::<Token![=]>()?;
			let value = input.parse::<TypePath>()?;
			match ident.to_string().as_str() {
				"result" => if result.is_none() {
					result = Some(value);
				} else {
					return Err(Error::new(ident.span(), "duplicate argument name"));
				},
				"error" => if error.is_none() {
					error = Some(value)
				} else {
					return Err(Error::new(ident.span(), "duplicate argument name"));
				},
				_ => return Err(Error::new(ident.span(), "unknown argument name; valid names are: 'result' and 'error'")),
			}

			Ok(())
		};

		read_arg()?;
		if input.is_empty() { return Ok(Self { result, error }) }
		input.parse::<token::Comma>()?;
		read_arg()?;

		Ok(Self {
			result,
			error,
		})
	}
}