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}
65
66#[derive(Debug, Clone)]
73pub struct IdConflict<Id> {
74 pub attempted: Id,
75 pub diagnostics: ConstraintDiagnostics,
76}
77impl<Id> IdConflict<Id> {
78 #[doc(hidden)]
79 pub fn new(
80 attempted: Id,
81 table: &'static str,
82 constraint: &'static str,
83 kind: ConstraintKind,
84 source: sqlx::Error,
85 ) -> Self {
86 Self {
87 attempted,
88 diagnostics: ConstraintDiagnostics {
89 table,
90 constraint,
91 kind,
92 source: Arc::new(source),
93 },
94 }
95 }
96}
97impl<Id> fmt::Display for IdConflict<Id> {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 self.diagnostics.fmt(f)
100 }
101}
102impl<Id: fmt::Debug> Error for IdConflict<Id> {
103 fn source(&self) -> Option<&(dyn Error + 'static)> {
104 Some(&self.diagnostics)
105 }
106}