Rever safe results handling

This commit is contained in:
Manuel Cillero 2023-10-26 15:12:24 +02:00
parent 46ccbc10eb
commit ce3e0257bf
7 changed files with 66 additions and 135 deletions

View file

@ -60,7 +60,6 @@ impl MigrationTrait for Migration {
.values_panic(vec!["administrator".into(), "3".into()]),
)
.await
.unwrap_or_error(|e| DbErr::Custom(e.message()))
.map(|_| ())
}

View file

@ -124,7 +124,7 @@ pub fn run_migrations() {
}
Migrator::up(SchemaManagerConnection::Connection(dbconn), None)
})
.expect_or_log(L10n::l("db_migration_fail").message().as_str());
.expect_or_log(L10n::l("db_migration_fail").error().as_str());
run_now({
struct Migrator;
@ -139,7 +139,7 @@ pub fn run_migrations() {
}
Migrator::down(SchemaManagerConnection::Connection(dbconn), None)
})
.expect_or_log(L10n::l("db_migration_fail").message().as_str());
.expect_or_log(L10n::l("db_migration_fail").error().as_str());
}
}

View file

@ -1,11 +1,11 @@
//! Acceso unificado y normalizado a base de datos.
use crate::locale::L10n;
use crate::result::{SafeResult, TraceErr};
use crate::{config, trace, LazyStatic, ResultExt};
pub use url::Url as DbUri;
pub use sea_orm::error::{DbErr, RuntimeErr};
pub use sea_orm::{DatabaseConnection as DbConn, ExecResult, QueryResult};
use sea_orm::{ConnectOptions, ConnectionTrait, Database, DatabaseBackend, Statement};
@ -70,18 +70,18 @@ pub(crate) static DBCONN: LazyStatic<Option<DbConn>> = LazyStatic::new(|| {
db_opt.max_connections(config::SETTINGS.database.max_pool_size);
db_opt
}))
.expect_or_log(L10n::l("db_connection_fail").message().as_str()),
.expect_or_log(L10n::l("db_connection_fail").to_string().as_str()),
)
} else {
None
}
});
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<Vec<QueryResult>>> {
pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Vec<QueryResult>, DbErr> {
match &*DBCONN {
Some(dbconn) => {
let dbbackend = dbconn.get_database_backend();
match dbconn
dbconn
.query_all(Statement::from_string(
dbbackend,
match dbbackend {
@ -91,23 +91,18 @@ pub async fn query<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<V
},
))
.await
{
Ok(result) => SafeResult::Ok(Some(result)),
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
}
}
None => SafeResult::Err(TraceErr::trace(
L10n::l("db_connection_not_initialized"),
None,
)),
None => Err(DbErr::Conn(RuntimeErr::Internal(
L10n::l("db_connection_not_initialized").trace(),
))),
}
}
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<QueryResult>> {
pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> Result<Option<QueryResult>, DbErr> {
match &*DBCONN {
Some(dbconn) => {
let dbbackend = dbconn.get_database_backend();
match dbconn
dbconn
.query_one(Statement::from_string(
dbbackend,
match dbbackend {
@ -117,34 +112,24 @@ pub async fn exec<Q: QueryStatementWriter>(stmt: &mut Q) -> SafeResult<Option<Qu
},
))
.await
{
Ok(result) => SafeResult::Ok(result),
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
}
}
None => SafeResult::Err(TraceErr::trace(
L10n::l("db_connection_not_initialized"),
None,
)),
None => Err(DbErr::Conn(RuntimeErr::Internal(
L10n::l("db_connection_not_initialized").trace(),
))),
}
}
pub async fn exec_raw(stmt: String) -> SafeResult<Option<ExecResult>> {
pub async fn exec_raw(stmt: String) -> Result<ExecResult, DbErr> {
match &*DBCONN {
Some(dbconn) => {
let dbbackend = dbconn.get_database_backend();
match dbconn
dbconn
.execute(Statement::from_string(dbbackend, stmt))
.await
{
Ok(result) => SafeResult::Ok(Some(result)),
Err(e) => SafeResult::Err(TraceErr::error(L10n::n(e.to_string()), None)),
}
}
None => SafeResult::Err(TraceErr::trace(
L10n::l("db_connection_not_initialized"),
None,
)),
None => Err(DbErr::Conn(RuntimeErr::Internal(
L10n::l("db_connection_not_initialized").trace(),
))),
}
}

View file

@ -129,9 +129,6 @@ static_locales!(LOCALES_PAGETOP);
// PUBLIC API.
// *************************************************************************************************
// Handling safe results.
pub mod result;
// Functions and macro helpers.
pub mod util;

View file

@ -88,8 +88,7 @@
//! ```
use crate::html::{Markup, PreEscaped};
use crate::result::{SafeResult, TraceErr};
use crate::{config, kv, LazyStatic, LOCALES_PAGETOP};
use crate::{config, kv, trace, LazyStatic, LOCALES_PAGETOP};
pub use fluent_templates;
pub use unic_langid::LanguageIdentifier;
@ -118,22 +117,21 @@ static FALLBACK_LANGID: LazyStatic<LanguageIdentifier> = LazyStatic::new(|| lang
/// Almacena el Identificador de Idioma Unicode
/// ([Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier))
/// global para la aplicación a partir de `SETTINGS.app.language`.
pub(crate) static LANGID: LazyStatic<&LanguageIdentifier> =
LazyStatic::new(|| langid_for(config::SETTINGS.app.language.as_str()).unwrap_or_fallback());
pub(crate) static LANGID: LazyStatic<&LanguageIdentifier> = LazyStatic::new(|| {
langid_for(config::SETTINGS.app.language.as_str()).unwrap_or(&FALLBACK_LANGID)
});
pub fn langid_for(language: impl Into<String>) -> SafeResult<&'static LanguageIdentifier> {
pub fn langid_for(language: impl Into<String>) -> Result<&'static LanguageIdentifier, String> {
let language = language.into();
match LANGUAGES.get(language.as_str()) {
Some((langid, _)) => SafeResult::Ok(langid),
Some((langid, _)) => Ok(langid),
None => {
if language.is_empty() {
SafeResult::Ok(&FALLBACK_LANGID)
Ok(&FALLBACK_LANGID)
} else {
SafeResult::Err(TraceErr::warn(
L10n::l(LANGUAGE_SET_FAILURE)
.with_arg("language", config::SETTINGS.app.language.as_str()),
&FALLBACK_LANGID,
))
Err(L10n::l(LANGUAGE_SET_FAILURE)
.with_arg("language", config::SETTINGS.app.language.as_str())
.warn())
}
}
}
@ -238,7 +236,43 @@ impl L10n {
}
}
pub(crate) fn message(&self) -> String {
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
PreEscaped(self.using(langid).unwrap_or_default())
}
pub fn trace(&self) -> String {
let message = self.to_string();
trace::trace!(message);
message
}
pub fn debug(&self) -> String {
let message = self.to_string();
trace::debug!(message);
message
}
pub fn info(&self) -> String {
let message = self.to_string();
trace::info!(message);
message
}
pub fn warn(&self) -> String {
let message = self.to_string();
trace::warn!(message);
message
}
pub fn error(&self) -> String {
let message = self.to_string();
trace::error!(message);
message
}
}
impl ToString for L10n {
fn to_string(&self) -> String {
match &self.op {
L10nOp::None => "".to_owned(),
L10nOp::Text(text) => text.to_owned(),
@ -263,8 +297,4 @@ impl L10n {
},
}
}
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
PreEscaped(self.using(langid).unwrap_or_default())
}
}

View file

@ -6,9 +6,6 @@ pub use crate::{concat_string, fn_builder, main, paste, test};
// Global.
pub use crate::{Handle, HashMapResources, LazyStatic, ResultExt, Weight};
// Handling safe results.
pub use crate::result::{SafeResult, TraceErr};
// Functions and macro helpers.
pub use crate::util;
pub use crate::{kv, new_handle};

View file

@ -1,77 +0,0 @@
//! Handling safe results.
use crate::locale::L10n;
use crate::trace;
pub struct TraceErr<T> {
message: String,
fallback: T,
}
impl<T> TraceErr<T> {
pub fn trace(trace: L10n, fallback: T) -> Self {
let message = trace.message();
trace::trace!(message);
TraceErr { message, fallback }
}
pub fn debug(trace: L10n, fallback: T) -> Self {
let message = trace.message();
trace::debug!(message);
TraceErr { message, fallback }
}
pub fn info(trace: L10n, fallback: T) -> Self {
let message = trace.message();
trace::info!(message);
TraceErr { message, fallback }
}
pub fn warn(trace: L10n, fallback: T) -> Self {
let message = trace.message();
trace::warn!(message);
TraceErr { message, fallback }
}
pub fn error(trace: L10n, fallback: T) -> Self {
let message = trace.message();
trace::error!(message);
TraceErr { message, fallback }
}
// TraceErr GETTERS.
pub fn message(self) -> String {
self.message
}
pub fn fallback(self) -> T {
self.fallback
}
}
pub enum SafeResult<T> {
Ok(T),
Err(TraceErr<T>),
}
impl<T> SafeResult<T> {
#[inline]
pub fn unwrap_or_error<F, E>(self, f: F) -> Result<T, E>
where
F: FnOnce(TraceErr<T>) -> E,
{
match self {
SafeResult::Ok(r) => Ok(r),
SafeResult::Err(e) => Err(f(e)),
}
}
#[inline]
pub fn unwrap_or_fallback(self) -> T {
match self {
SafeResult::Ok(r) => r,
SafeResult::Err(e) => e.fallback(),
}
}
}