use crate::{Exchange, Span};
use std::fmt;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub enum OnMalformed {
#[default]
Abort,
Skip,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct ParseOptions {
pub on_malformed_record: OnMalformed,
}
impl ParseOptions {
#[must_use]
pub const fn strict() -> Self {
Self {
on_malformed_record: OnMalformed::Abort,
}
}
#[must_use]
pub const fn lenient() -> Self {
Self {
on_malformed_record: OnMalformed::Skip,
}
}
#[must_use]
pub const fn on_malformed_record(mut self, policy: OnMalformed) -> Self {
self.on_malformed_record = policy;
self
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Severity {
#[default]
Warning,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Diagnostic {
severity: Severity,
span: Span,
detail: String,
}
impl Diagnostic {
pub(crate) fn skipped_record(span: Span, detail: impl Into<String>) -> Self {
Self {
severity: Severity::Warning,
span,
detail: detail.into(),
}
}
#[must_use]
pub const fn severity(&self) -> Severity {
self.severity
}
#[must_use]
pub const fn span(&self) -> Span {
self.span
}
#[must_use]
pub fn detail(&self) -> &str {
&self.detail
}
}
impl fmt::Display for Diagnostic {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"STEP warning at bytes {}..{}: {}",
self.span.start, self.span.end, self.detail
)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParseOutcome {
pub exchange: Exchange,
pub diagnostics: Vec<Diagnostic>,
}
impl ParseOutcome {
#[must_use]
pub fn is_lossless(&self) -> bool {
self.diagnostics.is_empty()
}
}