1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use {
	crate::{
		AlterError, CSVDatabaseError, CreateError, DatabaseError, ExecuteError, FetchError,
		InterfaceError, JoinError, ManualError, MemoryDatabaseError, PlanError, QueryError,
		RecipeError, RowError, SelectError, SheetDatabaseError, TableError, ValidateError,
		ValueError,
	},
	serde::Serialize,
	std::marker::{Send, Sync},
	thiserror::Error as ThisError,
};

#[derive(ThisError, Serialize, Debug, PartialEq)]
pub enum WIPError {
	#[error("TODO")]
	TODO,
	#[error("{0}")]
	Debug(String),
}

#[derive(ThisError, Serialize, Debug)]
pub enum Error {
	#[error(transparent)]
	#[serde(with = "stringify")]
	Database(#[from] Box<dyn std::error::Error>),

	#[cfg(feature = "odbc-database")]
	#[error(transparent)]
	#[serde(with = "stringify")]
	ODBC(#[from] odbc_api::Error),

	#[error(transparent)]
	Execute(#[from] ExecuteError),
	#[error(transparent)]
	Alter(#[from] AlterError),
	#[error(transparent)]
	Create(#[from] CreateError),
	#[error(transparent)]
	Fetch(#[from] FetchError),
	#[error(transparent)]
	Select(#[from] SelectError),
	#[error(transparent)]
	Row(#[from] RowError),
	#[error(transparent)]
	Table(#[from] TableError),
	#[error(transparent)]
	Value(#[from] ValueError),
	#[error(transparent)]
	Recipe(#[from] RecipeError),
	#[error(transparent)]
	Join(#[from] JoinError),
	#[error(transparent)]
	Plan(#[from] PlanError),
	#[error(transparent)]
	Manual(#[from] ManualError),
	#[error(transparent)]
	Query(#[from] QueryError),
	#[error(transparent)]
	Validate(#[from] ValidateError),
	#[error(transparent)]
	WIP(#[from] WIPError),
	#[error(transparent)]
	DatabaseImplementation(#[from] DatabaseError),
	#[error(transparent)]
	CSVDatabase(#[from] CSVDatabaseError),
	#[error(transparent)]
	SheetDatabase(#[from] SheetDatabaseError),
	#[error(transparent)]
	MemoryDatabase(#[from] MemoryDatabaseError),
	#[error(transparent)]
	Interface(#[from] InterfaceError),
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

pub type Result<T> = std::result::Result<T, Error>;
pub type MutResult<T, U> = std::result::Result<(T, U), (T, Error)>;

impl PartialEq for Error {
	fn eq(&self, other: &Error) -> bool {
		use Error::*;

		match (self, other) {
			(Execute(l), Execute(r)) => l == r,
			(Alter(l), Alter(r)) => l == r,
			(Create(l), Create(r)) => l == r,
			(Fetch(l), Fetch(r)) => l == r,
			(Select(l), Select(r)) => l == r,
			(Row(l), Row(r)) => l == r,
			(Table(l), Table(r)) => l == r,
			(Value(l), Value(r)) => l == r,
			(Recipe(l), Recipe(r)) => l == r,
			(Join(l), Join(r)) => l == r,
			(Plan(l), Plan(r)) => l == r,
			(Manual(l), Manual(r)) => l == r,
			(Query(l), Query(r)) => l == r,
			(Validate(l), Validate(r)) => l == r,
			(WIP(l), WIP(r)) => l == r,
			(DatabaseImplementation(l), DatabaseImplementation(r)) => l == r,
			(CSVDatabase(l), CSVDatabase(r)) => l == r,
			(SheetDatabase(l), SheetDatabase(r)) => l == r,
			(Interface(l), Interface(r)) => l == r,
			(MemoryDatabase(l), MemoryDatabase(r)) => l == r,
			_ => false,
		}
	}
}

mod stringify {
	use {serde::Serializer, std::fmt::Display};

	pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
	where
		T: Display,
		S: Serializer,
	{
		serializer.collect_str(value)
	}
}