use serde_json::Value;
mod error_fmt;
mod hints;
mod semantic;
mod truncation;
mod validate;
pub use error_fmt::*;
pub use hints::*;
pub use semantic::*;
pub use truncation::*;
pub use validate::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RepairKind {
NullStripped,
JsonStringToArray,
ObjectToArray,
BareStringToArray,
MdLinkUnwrapped,
TruncationFixed,
}
#[allow(dead_code)]
impl RepairKind {
pub fn as_str(self) -> &'static str {
match self {
RepairKind::NullStripped => "null_stripped",
RepairKind::JsonStringToArray => "json_string_to_array",
RepairKind::ObjectToArray => "object_to_array",
RepairKind::BareStringToArray => "bare_string_to_array",
RepairKind::MdLinkUnwrapped => "md_link_unwrapped",
RepairKind::TruncationFixed => "truncation_fixed",
}
}
pub const ALL: &'static [RepairKind] = &[
RepairKind::NullStripped,
RepairKind::JsonStringToArray,
RepairKind::ObjectToArray,
RepairKind::BareStringToArray,
RepairKind::MdLinkUnwrapped,
RepairKind::TruncationFixed,
];
}
#[derive(Debug, Clone)]
pub struct RepairResult {
pub repaired: Value,
pub kinds: Vec<RepairKind>,
pub notes: Vec<String>,
}
#[derive(Debug, Default)]
pub struct RepairStats {
null_stripped: std::sync::atomic::AtomicU64,
json_string_to_array: std::sync::atomic::AtomicU64,
object_to_array: std::sync::atomic::AtomicU64,
bare_string_to_array: std::sync::atomic::AtomicU64,
md_link_unwrapped: std::sync::atomic::AtomicU64,
truncation_fixed: std::sync::atomic::AtomicU64,
invalid: std::sync::atomic::AtomicU64,
}
impl RepairStats {
pub fn new() -> Self {
Self::default()
}
pub fn record(&self, kind: RepairKind) {
use std::sync::atomic::Ordering;
let cell = match kind {
RepairKind::NullStripped => &self.null_stripped,
RepairKind::JsonStringToArray => &self.json_string_to_array,
RepairKind::ObjectToArray => &self.object_to_array,
RepairKind::BareStringToArray => &self.bare_string_to_array,
RepairKind::MdLinkUnwrapped => &self.md_link_unwrapped,
RepairKind::TruncationFixed => &self.truncation_fixed,
};
cell.fetch_add(1, Ordering::Relaxed);
}
pub fn record_invalid(&self) {
self.invalid
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
pub fn snapshot(&self) -> RepairStatsSnapshot {
use std::sync::atomic::Ordering;
RepairStatsSnapshot {
null_stripped: self.null_stripped.load(Ordering::Relaxed),
json_string_to_array: self.json_string_to_array.load(Ordering::Relaxed),
object_to_array: self.object_to_array.load(Ordering::Relaxed),
bare_string_to_array: self.bare_string_to_array.load(Ordering::Relaxed),
md_link_unwrapped: self.md_link_unwrapped.load(Ordering::Relaxed),
truncation_fixed: self.truncation_fixed.load(Ordering::Relaxed),
invalid: self.invalid.load(Ordering::Relaxed),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct RepairStatsSnapshot {
pub null_stripped: u64,
pub json_string_to_array: u64,
pub object_to_array: u64,
pub bare_string_to_array: u64,
pub md_link_unwrapped: u64,
pub truncation_fixed: u64,
pub invalid: u64,
}
impl RepairStatsSnapshot {
pub fn total_successful(&self) -> u64 {
self.null_stripped
+ self.json_string_to_array
+ self.object_to_array
+ self.bare_string_to_array
+ self.md_link_unwrapped
+ self.truncation_fixed
}
pub fn is_empty(&self) -> bool {
self.total_successful() == 0 && self.invalid == 0
}
}
#[cfg(test)]
mod tests;