1use std::{error::Error, fmt, sync::Arc};
2
3use crate::ConstraintKind;
4
5#[derive(Debug, Clone)]
7pub struct ConstraintDiagnostics {
8 pub table: &'static str,
9 pub constraint: &'static str,
10 pub kind: ConstraintKind,
11 source: Arc<sqlx::Error>,
12}
13impl fmt::Display for ConstraintDiagnostics {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(
16 f,
17 "constraint violation on {} ({})",
18 self.table, self.constraint
19 )
20 }
21}
22impl Error for ConstraintDiagnostics {
23 fn source(&self) -> Option<&(dyn Error + 'static)> {
24 Some(self.source.as_ref())
25 }
26}
27
28#[derive(Debug, Clone)]
31pub struct ConstraintConflict<V> {
32 pub attempted: Option<V>,
33 pub diagnostics: ConstraintDiagnostics,
34}
35impl<V> ConstraintConflict<V> {
36 #[doc(hidden)]
37 pub fn new(
38 attempted: Option<V>,
39 table: &'static str,
40 constraint: &'static str,
41 kind: ConstraintKind,
42 source: sqlx::Error,
43 ) -> Self {
44 Self {
45 attempted,
46 diagnostics: ConstraintDiagnostics {
47 table,
48 constraint,
49 kind,
50 source: Arc::new(source),
51 },
52 }
53 }
54}
55impl<V> fmt::Display for ConstraintConflict<V> {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 self.diagnostics.fmt(f)
58 }
59}
60impl<V: fmt::Debug> Error for ConstraintConflict<V> {
61 fn source(&self) -> Option<&(dyn Error + 'static)> {
62 Some(&self.diagnostics)
63 }
64}