use crate::report::{
Confidence, ErrorKey, ErrorLoc, LogReportMetadata, LogReportPointers, LogReportStyle,
PointedMessage, Severity, log,
};
pub fn tips(key: ErrorKey) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, Severity::Tips)
}
pub fn untidy(key: ErrorKey) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, Severity::Untidy)
}
pub fn warn(key: ErrorKey) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, Severity::Warning)
}
pub fn err(key: ErrorKey) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, Severity::Error)
}
pub fn fatal(key: ErrorKey) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, Severity::Fatal)
}
pub fn report(key: ErrorKey, severity: Severity) -> ReportBuilderStage1 {
ReportBuilderStage1::new(key, severity)
}
#[derive(Debug, Clone, Copy)]
#[must_use]
pub struct ReportBuilderStage1(ErrorKey, Severity, Confidence);
impl ReportBuilderStage1 {
fn new(key: ErrorKey, severity: Severity) -> Self {
Self(key, severity, Confidence::Reasonable)
}
pub fn weak(mut self) -> Self {
self.2 = Confidence::Weak;
self
}
pub fn strong(mut self) -> Self {
self.2 = Confidence::Strong;
self
}
pub fn conf(mut self, conf: Confidence) -> Self {
self.2 = conf;
self
}
pub fn msg<S: Into<String>>(self, msg: S) -> ReportBuilderStage2 {
ReportBuilderStage2 { stage1: self, msg: msg.into(), info: None, wiki: None }
}
}
#[derive(Debug)]
#[must_use]
pub struct ReportBuilderStage2 {
stage1: ReportBuilderStage1,
msg: String,
info: Option<String>,
wiki: Option<String>,
}
impl ReportBuilderStage2 {
pub fn info<S: Into<String>>(mut self, info: S) -> Self {
let info = info.into();
self.info = if info.is_empty() { None } else { Some(info) };
self
}
pub fn opt_info<S: Into<String>>(mut self, info: Option<S>) -> Self {
self.info = info.map(Into::into);
self
}
#[allow(dead_code)]
pub fn wiki<S: Into<String>>(mut self, wiki: S) -> Self {
let wiki = wiki.into();
self.wiki = if wiki.is_empty() { None } else { Some(wiki) };
self
}
pub fn loc<E: ErrorLoc>(self, eloc: E) -> ReportBuilderFull {
let length = eloc.loc_length();
ReportBuilderFull {
stage1: self.stage1,
msg: self.msg,
info: self.info,
wiki: self.wiki,
pointers: vec![PointedMessage { loc: eloc.into_loc(), length, msg: None }],
}
}
pub fn loc_msg<E: ErrorLoc, S: Into<String>>(self, eloc: E, msg: S) -> ReportBuilderFull {
let length = eloc.loc_length();
ReportBuilderFull {
stage1: self.stage1,
msg: self.msg,
info: self.info,
wiki: self.wiki,
pointers: vec![PointedMessage { loc: eloc.into_loc(), length, msg: Some(msg.into()) }],
}
}
pub fn pointers(self, pointers: LogReportPointers) -> ReportBuilderFull {
ReportBuilderFull {
stage1: self.stage1,
msg: self.msg,
info: self.info,
wiki: self.wiki,
pointers,
}
}
pub fn abbreviated<E: ErrorLoc>(self, eloc: E) -> ReportBuilderAbbreviated {
ReportBuilderAbbreviated {
stage1: self.stage1,
msg: self.msg,
info: self.info,
wiki: self.wiki,
pointers: vec![PointedMessage { loc: eloc.into_loc(), length: 0, msg: None }],
}
}
}
#[derive(Debug)]
#[must_use]
pub struct ReportBuilderFull {
stage1: ReportBuilderStage1,
msg: String,
info: Option<String>,
wiki: Option<String>,
pointers: LogReportPointers,
}
impl ReportBuilderFull {
pub fn loc_msg<E: ErrorLoc, S: Into<String>>(mut self, eloc: E, msg: S) -> Self {
let length = eloc.loc_length();
self.pointers.push(PointedMessage { loc: eloc.into_loc(), length, msg: Some(msg.into()) });
self
}
pub fn opt_loc_msg<E: ErrorLoc, S: Into<String>>(mut self, eloc: Option<E>, msg: S) -> Self {
if let Some(eloc) = eloc {
let length = eloc.loc_length();
self.pointers.push(PointedMessage {
loc: eloc.into_loc(),
length,
msg: Some(msg.into()),
});
}
self
}
pub fn build(self) -> (LogReportMetadata, LogReportPointers) {
(
LogReportMetadata {
key: self.stage1.0,
severity: self.stage1.1,
confidence: self.stage1.2,
msg: self.msg,
info: self.info,
wiki: self.wiki,
style: LogReportStyle::Full,
},
self.pointers,
)
}
pub fn push(self) {
log(self.build());
}
}
#[derive(Debug)]
#[must_use]
pub struct ReportBuilderAbbreviated {
stage1: ReportBuilderStage1,
msg: String,
info: Option<String>,
wiki: Option<String>,
pointers: LogReportPointers,
}
impl ReportBuilderAbbreviated {
pub fn build(self) -> (LogReportMetadata, LogReportPointers) {
(
LogReportMetadata {
key: self.stage1.0,
severity: self.stage1.1,
confidence: self.stage1.2,
msg: self.msg,
info: self.info,
wiki: self.wiki,
style: LogReportStyle::Abbreviated,
},
self.pointers,
)
}
pub fn push(self) {
log(self.build());
}
}