use super::capture::capture;
use super::emit::emit;
use super::place::place;
use super::types::{Emittable, Spans};
use crate::diagnostic::Diagnostic;
use crate::expansion::Expansion;
use crate::kind::Kind;
use crate::token::CapturedInput;
use proc_macro::TokenStream;
#[must_use]
pub fn expand<K: Kind>(
input: TokenStream,
road: impl FnOnce(CapturedInput) -> Result<Expansion<K>, Diagnostic>,
) -> TokenStream {
expand_emittable(input, road)
}
#[must_use]
pub fn expand_emittable<E: Emittable>(
input: TokenStream,
road: impl FnOnce(CapturedInput) -> Result<E, Diagnostic>,
) -> TokenStream {
let mut spans = Spans::empty();
match capture(input, &mut spans) {
Ok(captured) => match road(captured) {
Ok(expansion) => match emit(&expansion, &spans) {
Ok(tokens) => tokens,
Err(refusal) => super::place::emission_refused(&refusal),
},
Err(diagnostic) => place(&diagnostic, &spans),
},
Err(refusal) => refusal.placed(&spans),
}
}
#[must_use]
pub fn expand_on<K: Kind>(
body: TokenStream,
item: TokenStream,
road: impl FnOnce(CapturedInput, CapturedInput) -> Result<Expansion<K>, Diagnostic>,
) -> TokenStream {
let mut spans = Spans::empty();
let captured_body = match capture(body, &mut spans) {
Ok(captured) => captured,
Err(refusal) => return refusal.placed(&spans),
};
let captured_item = match capture(item, &mut spans) {
Ok(captured) => captured,
Err(refusal) => return refusal.placed(&spans),
};
match road(captured_body, captured_item) {
Ok(expansion) => match emit(&expansion, &spans) {
Ok(tokens) => tokens,
Err(refusal) => super::place::emission_refused(&refusal),
},
Err(diagnostic) => place(&diagnostic, &spans),
}
}