use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WarnCode {
ReturningDropped,
SequenceDropped,
OnDuplicateKeyUnsupported,
RawPassthrough,
}
impl WarnCode {
pub fn as_str(self) -> &'static str {
match self {
WarnCode::ReturningDropped => "RETURNING_DROPPED",
WarnCode::SequenceDropped => "SEQUENCE_DROPPED",
WarnCode::OnDuplicateKeyUnsupported => "ON_DUPLICATE_KEY_UNSUPPORTED",
WarnCode::RawPassthrough => "RAW_PASSTHROUGH",
}
}
}
impl fmt::Display for WarnCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone)]
pub struct Warning {
pub code: WarnCode,
pub message: String,
}
impl Warning {
pub fn new(code: WarnCode, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
}
}
}
impl fmt::Display for Warning {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "warning: {} {}", self.code, self.message)
}
}
pub trait WarnSink {
fn warn(&mut self, w: Warning);
fn count(&self) -> usize;
}
pub struct StderrSink {
n: usize,
}
impl Default for StderrSink {
fn default() -> Self {
Self::new()
}
}
impl StderrSink {
pub fn new() -> Self {
Self { n: 0 }
}
}
impl WarnSink for StderrSink {
fn warn(&mut self, w: Warning) {
self.n += 1;
eprintln!("{w}");
}
fn count(&self) -> usize {
self.n
}
}
#[derive(Debug, Default)]
pub struct CollectingSink {
pub items: Vec<Warning>,
}
impl WarnSink for CollectingSink {
fn warn(&mut self, w: Warning) {
self.items.push(w);
}
fn count(&self) -> usize {
self.items.len()
}
}