move core result into core utils
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
5cb0a5f676
commit
c769fcc347
12 changed files with 2 additions and 3 deletions
|
@ -10,6 +10,7 @@ pub mod json;
|
|||
pub mod math;
|
||||
pub mod mutex_map;
|
||||
pub mod rand;
|
||||
pub mod result;
|
||||
pub mod set;
|
||||
pub mod stream;
|
||||
pub mod string;
|
||||
|
|
15
src/core/utils/result.rs
Normal file
15
src/core/utils/result.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
mod debug_inspect;
|
||||
mod flat_ok;
|
||||
mod into_is_ok;
|
||||
mod log_debug_err;
|
||||
mod log_err;
|
||||
mod map_expect;
|
||||
mod not_found;
|
||||
mod unwrap_infallible;
|
||||
|
||||
pub use self::{
|
||||
debug_inspect::DebugInspect, flat_ok::FlatOk, into_is_ok::IntoIsOk, log_debug_err::LogDebugErr, log_err::LogErr,
|
||||
map_expect::MapExpect, not_found::NotFound, unwrap_infallible::UnwrapInfallible,
|
||||
};
|
||||
|
||||
pub type Result<T = (), E = crate::Error> = std::result::Result<T, E>;
|
52
src/core/utils/result/debug_inspect.rs
Normal file
52
src/core/utils/result/debug_inspect.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use super::Result;
|
||||
|
||||
/// Inspect Result values with release-mode elision.
|
||||
pub trait DebugInspect<T, E> {
|
||||
/// Inspects an Err contained value in debug-mode. In release-mode closure F
|
||||
/// is elided.
|
||||
#[must_use]
|
||||
fn debug_inspect_err<F: FnOnce(&E)>(self, f: F) -> Self;
|
||||
|
||||
/// Inspects an Ok contained value in debug-mode. In release-mode closure F
|
||||
/// is elided.
|
||||
#[must_use]
|
||||
fn debug_inspect<F: FnOnce(&T)>(self, f: F) -> Self;
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl<T, E> DebugInspect<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn debug_inspect<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(&T),
|
||||
{
|
||||
self.inspect(f)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn debug_inspect_err<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(&E),
|
||||
{
|
||||
self.inspect_err(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
impl<T, E> DebugInspect<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn debug_inspect<F>(self, _: F) -> Self
|
||||
where
|
||||
F: FnOnce(&T),
|
||||
{
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn debug_inspect_err<F>(self, _: F) -> Self
|
||||
where
|
||||
F: FnOnce(&E),
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
34
src/core/utils/result/flat_ok.rs
Normal file
34
src/core/utils/result/flat_ok.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use super::Result;
|
||||
|
||||
pub trait FlatOk<T> {
|
||||
/// Equivalent to .transpose().ok().flatten()
|
||||
fn flat_ok(self) -> Option<T>;
|
||||
|
||||
/// Equivalent to .transpose().ok().flatten().ok_or(...)
|
||||
fn flat_ok_or<E>(self, err: E) -> Result<T, E>;
|
||||
|
||||
/// Equivalent to .transpose().ok().flatten().ok_or_else(...)
|
||||
fn flat_ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
|
||||
}
|
||||
|
||||
impl<T, E> FlatOk<T> for Option<Result<T, E>> {
|
||||
#[inline]
|
||||
fn flat_ok(self) -> Option<T> { self.transpose().ok().flatten() }
|
||||
|
||||
#[inline]
|
||||
fn flat_ok_or<Ep>(self, err: Ep) -> Result<T, Ep> { self.flat_ok().ok_or(err) }
|
||||
|
||||
#[inline]
|
||||
fn flat_ok_or_else<Ep, F: FnOnce() -> Ep>(self, err: F) -> Result<T, Ep> { self.flat_ok().ok_or_else(err) }
|
||||
}
|
||||
|
||||
impl<T, E> FlatOk<T> for Result<Option<T>, E> {
|
||||
#[inline]
|
||||
fn flat_ok(self) -> Option<T> { self.ok().flatten() }
|
||||
|
||||
#[inline]
|
||||
fn flat_ok_or<Ep>(self, err: Ep) -> Result<T, Ep> { self.flat_ok().ok_or(err) }
|
||||
|
||||
#[inline]
|
||||
fn flat_ok_or_else<Ep, F: FnOnce() -> Ep>(self, err: F) -> Result<T, Ep> { self.flat_ok().ok_or_else(err) }
|
||||
}
|
60
src/core/utils/result/inspect_log.rs
Normal file
60
src/core/utils/result/inspect_log.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use std::fmt;
|
||||
|
||||
use tracing::Level;
|
||||
|
||||
use super::Result;
|
||||
use crate::error;
|
||||
|
||||
pub trait ErrLog<T, E>
|
||||
where
|
||||
E: fmt::Display,
|
||||
{
|
||||
fn log_err(self, level: Level) -> Self;
|
||||
|
||||
fn err_log(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.log_err(Level::ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ErrDebugLog<T, E>
|
||||
where
|
||||
E: fmt::Debug,
|
||||
{
|
||||
fn log_err_debug(self, level: Level) -> Self;
|
||||
|
||||
fn err_debug_log(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.log_err_debug(Level::ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> ErrLog<T, E> for Result<T, E>
|
||||
where
|
||||
E: fmt::Display,
|
||||
{
|
||||
#[inline]
|
||||
fn log_err(self, level: Level) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.inspect_err(|error| error::inspect_log_level(&error, level))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> ErrDebugLog<T, E> for Result<T, E>
|
||||
where
|
||||
E: fmt::Debug,
|
||||
{
|
||||
#[inline]
|
||||
fn log_err_debug(self, level: Level) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.inspect_err(|error| error::inspect_debug_log_level(&error, level))
|
||||
}
|
||||
}
|
10
src/core/utils/result/into_is_ok.rs
Normal file
10
src/core/utils/result/into_is_ok.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use super::Result;
|
||||
|
||||
pub trait IntoIsOk<T, E> {
|
||||
fn into_is_ok(self) -> bool;
|
||||
}
|
||||
|
||||
impl<T, E> IntoIsOk<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn into_is_ok(self) -> bool { self.is_ok() }
|
||||
}
|
26
src/core/utils/result/log_debug_err.rs
Normal file
26
src/core/utils/result/log_debug_err.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use tracing::Level;
|
||||
|
||||
use super::{DebugInspect, Result};
|
||||
use crate::error;
|
||||
|
||||
pub trait LogDebugErr<T, E: Debug> {
|
||||
#[must_use]
|
||||
fn err_debug_log(self, level: Level) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn log_debug_err(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.err_debug_log(Level::ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E: Debug> LogDebugErr<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn err_debug_log(self, level: Level) -> Self {
|
||||
self.debug_inspect_err(|error| error::inspect_debug_log_level(&error, level))
|
||||
}
|
||||
}
|
24
src/core/utils/result/log_err.rs
Normal file
24
src/core/utils/result/log_err.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use tracing::Level;
|
||||
|
||||
use super::Result;
|
||||
use crate::error;
|
||||
|
||||
pub trait LogErr<T, E: Display> {
|
||||
#[must_use]
|
||||
fn err_log(self, level: Level) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn log_err(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.err_log(Level::ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E: Display> LogErr<T, E> for Result<T, E> {
|
||||
#[inline]
|
||||
fn err_log(self, level: Level) -> Self { self.inspect_err(|error| error::inspect_log_level(&error, level)) }
|
||||
}
|
15
src/core/utils/result/map_expect.rs
Normal file
15
src/core/utils/result/map_expect.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use super::Result;
|
||||
|
||||
pub trait MapExpect<T> {
|
||||
/// Calls expect(msg) on the mapped Result value. This is similar to
|
||||
/// map(Result::unwrap) but composes an expect call and message without
|
||||
/// requiring a closure.
|
||||
fn map_expect(self, msg: &str) -> Option<T>;
|
||||
}
|
||||
|
||||
impl<T, E: Debug> MapExpect<T> for Option<Result<T, E>> {
|
||||
#[inline]
|
||||
fn map_expect(self, msg: &str) -> Option<T> { self.map(|result| result.expect(msg)) }
|
||||
}
|
12
src/core/utils/result/not_found.rs
Normal file
12
src/core/utils/result/not_found.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use super::Result;
|
||||
use crate::Error;
|
||||
|
||||
pub trait NotFound<T> {
|
||||
#[must_use]
|
||||
fn is_not_found(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<T> NotFound<T> for Result<T, Error> {
|
||||
#[inline]
|
||||
fn is_not_found(&self) -> bool { self.as_ref().is_err_and(Error::is_not_found) }
|
||||
}
|
17
src/core/utils/result/unwrap_infallible.rs
Normal file
17
src/core/utils/result/unwrap_infallible.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use std::convert::Infallible;
|
||||
|
||||
use super::{DebugInspect, Result};
|
||||
use crate::error;
|
||||
|
||||
pub trait UnwrapInfallible<T> {
|
||||
fn unwrap_infallible(self) -> T;
|
||||
}
|
||||
|
||||
impl<T> UnwrapInfallible<T> for Result<T, Infallible> {
|
||||
#[inline]
|
||||
fn unwrap_infallible(self) -> T {
|
||||
// SAFETY: Branchless unwrap for errors that can never happen. In debug
|
||||
// mode this is asserted.
|
||||
unsafe { self.debug_inspect_err(error::infallible).unwrap_unchecked() }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue