use std::collections::HashMap;
use proc_macro2::{Ident, Span};
use crate::parse::args::{MacroArg, RenameSource};
use crate::util::error_sink::ErrorSink;
mod pseudo_macros;
pub mod type_;
pub mod impl_;
fn versioned_ident(ident: &Ident, version: usize) -> Ident {
quote::format_ident!("{}V{}", ident, version)
}
#[derive(Default, Debug)]
pub struct Args {
pub start: usize,
pub end: Option<usize>,
base: bool,
enum_: bool,
pub rename: HashMap<RenameSource, Ident>,
}
impl Args {
pub fn from_raw(raw: Vec<(Span, MacroArg)>, errs: &mut ErrorSink) -> Self {
let mut res = Self::default();
let mut start_span = None::<(Span, bool)>;
let mut end_span = None::<(Span, bool)>;
let mut base_span = None::<(Span, bool)>;
let mut enum_span = None::<(Span, bool)>;
let mut rename_spans = HashMap::<RenameSource, (Span, bool)>::new();
for (span, arg) in raw {
match arg {
MacroArg::Start(start) => {
if let Some((fspan, errored)) = &mut start_span {
if !*errored {
errs.push(syn::Error::new(
*fspan,
"`start` can't be specified multiple times",
));
*errored = true;
}
errs.push(syn::Error::new(
span,
"`start` can't be specified multiple times",
));
} else {
res.start = start;
start_span = Some((span, false));
}
}
MacroArg::End(end) => {
if let Some((fspan, errored)) = &mut end_span {
if !*errored {
errs.push(syn::Error::new(
*fspan,
"`end` can't be specified multiple times",
));
*errored = true;
}
errs.push(syn::Error::new(
span,
"`end` can't be specified multiple times",
));
} else {
res.end = Some(end);
start_span = Some((span, false));
}
}
MacroArg::Enum => {
if let Some((fspan, errored)) = &mut enum_span {
if !*errored {
errs.push(syn::Error::new(
*fspan,
"`enum` can't be specified multiple times",
));
*errored = true;
}
errs.push(syn::Error::new(
span,
"`enum` can't be specified multiple times",
));
} else {
errs.push(syn::Error::new(span, "`enum` isn't implemented yet."));
res.enum_ = true;
enum_span = Some((span, false));
}
}
MacroArg::Base => {
if let Some((fspan, errored)) = &mut base_span {
if !*errored {
errs.push(syn::Error::new(
*fspan,
"`base` can't be specified multiple times",
));
*errored = true;
}
errs.push(syn::Error::new(
span,
"`base` can't be specified multiple times",
));
} else {
errs.push(syn::Error::new(span, "`base` isn't implemented yet."));
res.base = true;
base_span = Some((span, false));
}
}
MacroArg::Rename(src, ident) => {
if let Some((fspan, errored)) = rename_spans.get_mut(&src) {
if !*errored {
errs.push(syn::Error::new(
*fspan,
"`rename` can't be specified multiple times for the same source",
));
*errored = true;
}
errs.push(syn::Error::new(
span,
"`rename` can't be specified multiple times for the same source",
));
} else {
res.rename.insert(src, ident);
rename_spans.insert(src, (span, false));
}
}
}
}
res
}
}