use crate::span_map::SpanMap;
use libgraphql_parser::GraphQLErrorNoteKind;
use libgraphql_parser::GraphQLParseError;
use proc_macro2::Span;
use quote::quote_spanned;
pub(crate) fn convert_parse_errors_to_tokenstream(
errors: &[GraphQLParseError],
span_map: &SpanMap,
) -> proc_macro2::TokenStream {
let mut output = proc_macro2::TokenStream::new();
for error in errors {
let primary_span = span_map
.lookup_byte_offset(
error.source_span().start_inclusive.byte_offset() as u32,
)
.unwrap_or_else(Span::call_site);
let formatted_msg =
format_parse_error_message(error);
output.extend(quote_spanned! { primary_span =>
compile_error!(#formatted_msg);
});
for note in error.notes() {
if let Some(note_source_span) = ¬e.span
&& let Some(note_span) = span_map
.lookup_byte_offset(
note_source_span
.start_inclusive
.byte_offset() as u32,
) {
let note_msg =
format_parse_error_note(note);
output.extend(
quote_spanned! { note_span =>
compile_error!(#note_msg);
},
);
}
}
}
output
}
pub(crate) fn format_parse_error_message(
error: &GraphQLParseError,
) -> String {
let mut msg = error.message().to_string();
for note in error.notes() {
let prefix = match note.kind {
GraphQLErrorNoteKind::General => "note",
GraphQLErrorNoteKind::Help => "help",
GraphQLErrorNoteKind::Spec => "spec",
};
msg.push_str(&format!(
"\n = {prefix}: {}",
note.message,
));
}
msg
}
pub(crate) fn format_parse_error_note(
note: &libgraphql_parser::GraphQLErrorNote,
) -> String {
let prefix = match note.kind {
GraphQLErrorNoteKind::General => "note",
GraphQLErrorNoteKind::Help => "help",
GraphQLErrorNoteKind::Spec => "spec",
};
format!("{prefix}: {}", note.message)
}