1use postgres::error::SqlState;
4
5pub trait SqlError: Sized {
7 fn fk_violation<E, F: FnOnce() -> E>(self, f: F) -> Result<Self, E>;
9
10 fn is_fk_violation(&self) -> bool;
12
13 fn is_unique_violation(&self) -> bool;
15
16 fn unique_violation<E, F: FnOnce() -> E>(self, f: F) -> Result<Self, E>;
18}
19
20impl<T> SqlError for Result<T, postgres::Error> {
21 fn fk_violation<E, F: FnOnce() -> E>(self, f: F) -> Result<Self, E> {
22 if let Err(error) = &self
23 && let Some(code) = error.code()
24 && *code == SqlState::FOREIGN_KEY_VIOLATION
25 {
26 Err(f())
27 } else {
28 Ok(self)
29 }
30 }
31
32 fn unique_violation<E, F: FnOnce() -> E>(self, f: F) -> Result<Self, E> {
33 if let Err(error) = &self
34 && let Some(code) = error.code()
35 && *code == SqlState::UNIQUE_VIOLATION
36 {
37 Err(f())
38 } else {
39 Ok(self)
40 }
41 }
42
43 fn is_fk_violation(&self) -> bool {
44 if let Err(error) = &self
45 && let Some(code) = error.code()
46 && *code == SqlState::FOREIGN_KEY_VIOLATION
47 {
48 true
49 } else {
50 false
51 }
52 }
53
54 fn is_unique_violation(&self) -> bool {
55 if let Err(error) = &self
56 && let Some(code) = error.code()
57 && *code == SqlState::UNIQUE_VIOLATION
58 {
59 true
60 } else {
61 false
62 }
63 }
64}