1use std::{
4 error::Error,
5 fmt::{self, Display},
6 io,
7 str::Utf8Error,
8};
9
10#[cfg(feature = "fzn")]
11use winnow::error::{ContextError, ParseError};
12
13#[cfg(feature = "fzn")]
14use crate::fzn::Stream;
15
16#[derive(Debug)]
18pub enum FznParseError {
19 Io(io::Error),
21 Utf8Error(Utf8Error),
23 MissingSolveItem,
25 MultipleSolveItems,
27 SyntaxError(String),
29 LinkError(LinkError),
31}
32
33#[derive(Clone, PartialEq, Eq, Debug)]
35pub enum LinkError {
36 IdentifierError {
38 ident: String,
40 err: String,
42 },
43 UnknownReference(String),
45 NestedArray(String),
47 DuplicateDefinition(String),
49}
50
51impl Display for FznParseError {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 match self {
54 Self::Io(error) => write!(f, "error reading from source: {error}"),
55 Self::Utf8Error(error) => write!(f, "invalid utf8: {error}"),
56 Self::MissingSolveItem => write!(f, "missing solve item"),
57 Self::MultipleSolveItems => write!(f, "multiple solve items"),
58 Self::SyntaxError(error) => write!(f, "syntax error: {error}"),
59 Self::LinkError(error) => {
60 write!(f, "error linking model: {error}")
61 }
62 }
63 }
64}
65
66impl Error for FznParseError {}
67
68impl From<LinkError> for FznParseError {
69 fn from(error: LinkError) -> Self {
70 Self::LinkError(error)
71 }
72}
73
74#[cfg(feature = "fzn")]
75impl<Identifier, F> From<ParseError<Stream<'_, Identifier, F>, ContextError>> for FznParseError {
76 fn from(value: ParseError<Stream<'_, Identifier, F>, ContextError>) -> Self {
77 Self::SyntaxError(value.to_string())
78 }
79}
80
81impl From<Utf8Error> for FznParseError {
82 fn from(value: Utf8Error) -> Self {
83 Self::Utf8Error(value)
84 }
85}
86
87impl From<io::Error> for FznParseError {
88 fn from(value: io::Error) -> Self {
89 Self::Io(value)
90 }
91}
92
93impl Display for LinkError {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 match self {
97 Self::IdentifierError { ident, err } => {
98 write!(f, "failed to intern identifier `{ident}`: {err}")
99 }
100 Self::UnknownReference(name) => {
101 write!(f, "unknown FlatZinc variable or array `{name}`")
102 }
103 Self::NestedArray(name) => {
104 write!(f, "array identifier `{name}` used as part of an array")
105 }
106 Self::DuplicateDefinition(name) => {
107 write!(f, "duplicate definition of `{name}`")
108 }
109 }
110 }
111}
112
113impl Error for LinkError {}