use super::recovery_v2::SuggestionCategory;
use super::types::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParsingTier {
Fast,
Forgiving,
Repair,
}
impl From<SuggestionCategory> for RepairType {
fn from(category: SuggestionCategory) -> Self {
match category {
SuggestionCategory::MissingBracket => RepairType::InsertBracket,
SuggestionCategory::UnmatchedQuote => RepairType::BalanceQuotes,
SuggestionCategory::MissingComma => RepairType::InsertComma,
SuggestionCategory::TrailingComma => RepairType::RemoveComma,
SuggestionCategory::InvalidEscape => RepairType::ReplaceText,
SuggestionCategory::TypeMismatch => RepairType::TypeCoercion,
SuggestionCategory::StructuralError => RepairType::ReplaceText,
SuggestionCategory::Other => RepairType::ReplaceText,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RepairAction {
pub action_type: RepairType,
pub position: usize,
pub original: String,
pub replacement: String,
pub description: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RepairType {
InsertBracket,
RemoveBracket,
ReplaceBracket,
BalanceQuotes,
InsertComma,
RemoveComma,
InsertText,
ReplaceText,
ReplaceQuotes,
TypeCoercion,
QuoteKey,
}
#[derive(Debug, Clone)]
pub struct EnhancedParseResult<T> {
pub value: T,
pub errors: Vec<Error>,
pub repairs: Vec<RepairAction>,
pub parsing_tier: ParsingTier,
}
impl<T> EnhancedParseResult<T> {
pub fn success(value: T, tier: ParsingTier) -> Self {
Self {
value,
errors: Vec::new(),
repairs: Vec::new(),
parsing_tier: tier,
}
}
pub fn success_with_repairs(value: T, repairs: Vec<RepairAction>, tier: ParsingTier) -> Self {
Self {
value,
errors: Vec::new(),
repairs,
parsing_tier: tier,
}
}
pub fn failure(value: T, errors: Vec<Error>, tier: ParsingTier) -> Self {
Self {
value,
errors,
repairs: Vec::new(),
parsing_tier: tier,
}
}
pub fn failure_with_repairs(
value: T,
errors: Vec<Error>,
repairs: Vec<RepairAction>,
tier: ParsingTier,
) -> Self {
Self {
value,
errors,
repairs,
parsing_tier: tier,
}
}
#[inline(always)]
pub fn is_success(&self) -> bool {
self.errors.is_empty()
}
pub fn was_repaired(&self) -> bool {
!self.repairs.is_empty()
}
pub fn get_performance_tier(&self) -> ParsingTier {
self.parsing_tier
}
pub fn get_repair_summary(&self) -> String {
if self.repairs.is_empty() {
"No repairs needed".to_string()
} else {
let descriptions: Vec<&str> = self
.repairs
.iter()
.map(|r| r.description.as_str())
.collect();
format!(
"Applied {} repairs: {}",
self.repairs.len(),
descriptions.join(", ")
)
}
}
pub fn into_result(self) -> Result<T, Error> {
if self.is_success() {
Ok(self.value)
} else {
Err(self
.errors
.into_iter()
.next()
.unwrap_or_else(|| Error::Custom("Unknown error".to_string())))
}
}
}
impl<T> From<Result<T, Error>> for EnhancedParseResult<T>
where
T: Default,
{
fn from(result: Result<T, Error>) -> Self {
match result {
Ok(value) => Self::success(value, ParsingTier::Forgiving),
Err(error) => Self::failure(T::default(), vec![error], ParsingTier::Forgiving),
}
}
}