diff options
Diffstat (limited to 'src/db/mod.rs')
| -rw-r--r-- | src/db/mod.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/db/mod.rs b/src/db/mod.rs index fa3d74e..6005813 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -4,6 +4,7 @@ use std::str::FromStr; use hex_literal::hex; use sqlx::{ + error::{DatabaseError, ErrorKind}, migrate::{Migrate as _, MigrateDatabase as _}, sqlite::{Sqlite, SqliteConnectOptions, SqlitePool, SqlitePoolOptions}, }; @@ -161,3 +162,32 @@ impl<T> NotFound for Result<T, sqlx::Error> { self.optional()?.ok_or_else(map) } } + +pub trait Duplicate { + type Ok; + type Error; + + fn duplicate<E, F>(self, map: F) -> Result<Self::Ok, E> + where + E: From<Self::Error>, + F: FnOnce() -> E; +} + +impl<T> Duplicate for Result<T, sqlx::Error> { + type Ok = T; + type Error = sqlx::Error; + + fn duplicate<E, F>(self, map: F) -> Result<T, E> + where + E: From<sqlx::Error>, + F: FnOnce() -> E, + { + match self { + Ok(value) => Ok(value), + Err(error) => match error.as_database_error().map(DatabaseError::kind) { + Some(ErrorKind::UniqueViolation) => Err(map()), + _ => Err(error.into()), + }, + } + } +} |
