package paperformatter import ( "fmt" "strings" ) // ValidationError represents an error that occurs when input validation fails. // It includes the field name that failed validation and a descriptive message. type ValidationError struct { Field string Message string } func (e *ValidationError) Error() string { return fmt.Sprintf("validation error for %s: %s", e.Field, e.Message) } // FileError represents an error that occurs during file operations. // It includes the file path, the operation that failed (e.g., "read" or "write"), // and the underlying system error. type FileError struct { Path string Op string Wrapped error } func (e *FileError) Error() string { return fmt.Sprintf("file operation '%s' failed for '%s': %v", e.Op, e.Path, e.Wrapped) } func (e *FileError) Unwrap() error { return e.Wrapped } // JSONError represents an error that occurs during JSON parsing. // It wraps the underlying parsing error from the encoding/json package. type JSONError struct { Wrapped error } func (e *JSONError) Error() string { return fmt.Sprintf("JSON parsing error: %v", e.Wrapped) } func (e *JSONError) Unwrap() error { return e.Wrapped } // validatePaper checks if a Paper has all required fields. // Returns a ValidationError if any field is empty. func validatePaper(paper Paper) error { if paper.Title == "" { return &ValidationError{ Field: "title", Message: "title cannot be empty", } } if paper.Abstract == "" { return &ValidationError{ Field: "abstract", Message: "abstract cannot be empty", } } if paper.ArxivID == "" { return &ValidationError{ Field: "arxiv_id", Message: "arxiv_id cannot be empty", } } return nil } // validateEntry performs validation on an entire Entry, including its Paper. // It checks for required fields and valid decision values. // Returns a ValidationError if validation fails. func validateEntry(entry Entry) error { if err := validatePaper(entry.Paper); err != nil { return err } if entry.Decision == "" { return &ValidationError{ Field: "decision", Message: "decision cannot be empty", } } decision := strings.ToUpper(entry.Decision) if decision != "ACCEPT" && decision != "REJECT" { return &ValidationError{ Field: "decision", Message: "decision must be either 'accept' or 'reject'", } } if entry.Explanation == "" { return &ValidationError{ Field: "explanation", Message: "explanation cannot be empty", } } return nil }