Closed goto-bus-stop closed 9 months ago
https://github.com/apollographql/apollo-rs/pull/764 adds DiagnosticList::merge
which internally merges two SourceMap
. https://github.com/apollographql/apollo-rs/pull/764#discussion_r1410910183 points out that may be useful separately, but SourceMap
is a type alias for foreign types so we can have an inherent method SourceMap::merge
.
This now always uses colors and strips them out at the end, because ariadne
adds/strips colors as soon as you add a label, but here we would normally add the labels first and then decide whether they should be colored when it's time to print.
I added write
and fmt
inherent methods that consume self
so we only need one type. You have to pass in a SourceMap
in order to render, and you have to use the fmt
method inside your own fmt::{Display,Debug}
implementation, but you can't pass in a SourceMap
into your own fmt::{Display,Debug}
implementation except for having it available on the object. Soo yes this way would require exposing Diagnostic
(and DiagnosticList
probably) for people's custom errors, probably with a trait, which feels heavyweight, or expecting users to stick a SourceMap
in their errors wherever they are produced. Will experiment with it a bit in fed-next :)
Going to explore using the Diagnostic{sources, inner}
type that we use with a generic inner
error. You would have to wrap your error type with Diagnostic<>
to print it with pretty formatting. One motivation for that is that inner
errors would commonly derive thiserror
, so they already have a fmt::Display
implementation, and can't then also have pretty printing. (Unless users avoid thiserror and instead use DiagnosticReport
, which would be less nice)
The inner
type would have to implement a trait method to produce a diagnostic report which Diagnostic::fmt
would use.
I made some tweaks, added a changelog, and merged to stop myself from making more tweaks :sweat_smile:
This is an attempt to provide a reusable API on top of ariadne that downstream users can use to get similar formatting to apollo-rs. There is especially a need for this as ariadne uses character indices while apollo-rs uses byte indices, so we need to convert the numbers in between.
This adds public API:
ToDiagnostic::report(&mut CliReport)
- a trait method that custom errors can implement to provide advanced diagnostics for printing to CLICliReport
- a builder for advanced diagnostics, provided toToDiagnostic::report
Diagnostic<T>
- a wrapper for custom error types that provides pretty-printedfmt
andio::Write
output using theToDiagnostic
traitResultExt::to_diagnostic(SourceMap)
- extension method that wraps the error branch of aResult
in aDiagnostic<>
, so you don't need to do a verbose.map_err
danceThis API requires that users store the error location inside their own error type.
Inconveniences:
.to_report()
implementationDiagnosticList
, which may be useful, as collecting multiple errors is a common use case and having to write your ownfmt
impls and a custom wrapper type forVec<YourError>
is busy-workThe things to do here: