use alloc::string::String; use alloc::vec::Vec; use crate::span::Span; #[derive(Debug, Clone, PartialEq)] pub enum ParseError { Syntax { message: String, span: Span }, UnexpectedEof { expected: String, span: Span }, InvalidIdentifier { name: String, span: Span }, } impl ParseError { pub fn message(&self) -> String { match self { ParseError::Syntax { message, .. } => message.clone(), ParseError::UnexpectedEof { expected, .. } => { alloc::format!("Unexpected end of file, expected {}", expected) } ParseError::InvalidIdentifier { name, .. } => { alloc::format!("Invalid identifier: {}", name) } } } pub fn span(&self) -> Option { match self { ParseError::Syntax { span, .. } => Some(*span), ParseError::UnexpectedEof { span, .. } => Some(*span), ParseError::InvalidIdentifier { span, .. } => Some(*span), } } } #[derive(Debug, Clone, PartialEq)] pub enum ValidationError { DuplicateDefinition { name: String, first_span: Span, second_span: Span, module_namespace: String, }, UndefinedReference { name: String, span: Span, module_namespace: String, }, InvalidConstraint { message: String, span: Span, module_namespace: String, }, TypeMismatch { expected: String, found: String, span: Span, module_namespace: String, }, ConstraintTooPermissive { message: String, span: Span, module_namespace: String, }, ReservedName { name: String, span: Span, module_namespace: String, }, AmbiguousMain { name: String, namespace_suffix: String, first_span: Span, second_span: Span, module_namespace: String, }, MultipleMain { name: String, first_span: Span, second_span: Span, module_namespace: String, }, ConflictNotAllowed { name: String, namespace_suffix: String, span: Span, module_namespace: String, }, CircularImport { cycle: Vec, span: Span, module_namespace: String, }, UnusedImport { name: String, span: Span, module_namespace: String, }, } #[derive(Debug, Clone, Default)] pub struct ValidationErrors { pub errors: Vec, } impl ValidationErrors { pub fn new() -> Self { Self { errors: Vec::new() } } pub fn push(&mut self, error: ValidationError) { self.errors.push(error); } pub fn append(&mut self, other: &mut Self) { self.errors.append(&mut other.errors); } pub fn is_empty(&self) -> bool { self.errors.is_empty() } pub fn len(&self) -> usize { self.errors.len() } }