use std::fmt;
use std::hint::unreachable_unchecked;
use std::marker::PhantomData;
use std::ops::{ Deref, DerefMut };
use std::result::{ Iter, IterMut };
use crate::traits::node_tree::NodeTree;
use super::rid::RID;
use super::logger::Log;
use super::tree_option::TreeOption;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[must_use = "this `Result` may be an `Err` variant, which should be handled"]
pub struct TreeResult<'a, T, E> {
tree: *mut dyn NodeTree,
owner: RID,
object: Result<T, E>,
p_life: PhantomData<&'a ()>
}
impl <'a, T, E> TreeResult<'a, T, E> {
#[inline]
pub const unsafe fn new(tree: *mut dyn NodeTree, owner: RID, object: Result<T, E>) -> Self {
TreeResult { owner, tree, object, p_life: PhantomData }
}
#[inline]
pub fn to_result(self) -> Result<T, E> {
self.object
}
#[inline]
pub fn to_option(self) -> Option<T> {
self.object.ok()
}
#[inline]
pub const fn is_ok(&self) -> bool {
self.object.is_ok()
}
#[inline]
pub fn is_ok_and(&self, f: impl FnOnce(&T) -> bool) -> bool {
self.object.as_ref().is_ok_and(f)
}
#[inline]
pub const fn is_err(&self) -> bool {
!self.is_ok()
}
#[inline]
pub fn is_err_and(&self, f: impl FnOnce(&E) -> bool) -> bool {
self.object.as_ref().is_err_and(f)
}
#[inline]
pub fn ok(self) -> TreeOption<'a, T> {
unsafe {
TreeOption::new(self.tree, self.owner, self.object.ok())
}
}
#[inline]
pub fn err(self) -> TreeOption<'a, E> {
unsafe {
TreeOption::new(self.tree, self.owner, self.object.err())
}
}
#[inline]
pub fn as_ref(&self) -> TreeResult<&T, &E> {
match self.object.as_ref() {
Ok(object) => TreeResult { tree: self.tree, owner: self.owner, object: Ok(object), p_life: self.p_life },
Err(err) => TreeResult { tree: self.tree, owner: self.owner, object: Err(err), p_life: self.p_life }
}
}
#[inline]
pub fn as_mut(&mut self) -> TreeResult<&mut T, &mut E> {
match self.object.as_mut() {
Ok(object) => TreeResult { tree: self.tree, owner: self.owner, object: Ok(object), p_life: self.p_life },
Err(err) => TreeResult { tree: self.tree, owner: self.owner, object: Err(err), p_life: self.p_life }
}
}
#[inline]
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> TreeResult<'a, U, E> {
TreeResult { tree: self.tree, owner: self.owner, object: self.object.map(op), p_life: self.p_life }
}
#[inline]
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
self.object.map_or(default, f)
}
#[inline]
pub fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
self.object.map_or_else(default, f)
}
#[inline]
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> TreeResult<'a, T, F> {
TreeResult { tree: self.tree, owner: self.owner, object: self.object.map_err(op), p_life: self.p_life }
}
#[inline]
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
if let Ok(ref t) = self.object {
f(t);
}
self
}
#[inline]
pub fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self {
if let Err(ref e) = self.object {
f(e);
}
self
}
#[inline]
pub fn as_deref(&'a self) -> TreeResult<'a, &'a T::Target, &'a E>
where
T: Deref,
{ self.as_ref().map(|t| t.deref()) }
#[inline]
pub fn as_deref_mut(&'a mut self) -> TreeResult<'a, &'a mut T::Target, &'a mut E>
where
T: DerefMut,
{ self.as_mut().map(|t| t.deref_mut()) }
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
self.object.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.object.iter_mut()
}
pub fn expect(self, msg: &str) -> T
where
E: fmt::Debug
{
match self.object {
Ok(object) => object,
Err(ref err) => self.fail(msg, err)
}
}
pub fn unwrap(self) -> T
where
E: fmt::Debug
{
match self.object {
Ok(object) => object,
Err(ref err) => self.fail("called `TreeResult::unwrap()` on an `Err` value", err)
}
}
#[inline]
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
self.object.unwrap_or_default()
}
#[inline]
pub fn expect_err(self, msg: &str) -> E
where
T: fmt::Debug,
{
match self.object {
Ok(ref t) => self.fail(msg, &t),
Err(e) => e
}
}
#[inline]
pub fn unwrap_err(self) -> E
where
T: fmt::Debug,
{
match self.object {
Ok(ref t) => self.fail("called `TreeResult::unwrap_err()` on an `Ok` value", &t),
Err(e) => e
}
}
#[inline]
pub fn and<'b, U>(self, res: TreeResult<'b, U, E>) -> TreeResult<'a, U, E> {
match self.object {
Ok(_) => self.transfer_owner(res),
Err(e) => TreeResult { tree: self.tree, owner: self.owner, object: Err(e), p_life: self.p_life },
}
}
#[inline]
pub fn and_then<U, F: FnOnce(T) -> TreeResult<'a, U, E>>(self, op: F) -> TreeResult<'a, U, E> {
match self.object {
Ok(t) => op(t),
Err(e) => TreeResult { tree: self.tree, owner: self.owner, object: Err(e), p_life: self.p_life }
}
}
#[inline]
pub fn or<'b>(self, res: TreeResult<'b, T, E>) -> TreeResult<'a, T, E> {
match self.object {
Ok(_) => self,
Err(_) => self.transfer_owner(res)
}
}
#[inline]
pub fn or_else<'b, F, O: FnOnce(&E) -> TreeResult<'b, T, E>>(self, op: O) -> TreeResult<'a, T, E> {
match self.object {
Ok(_) => self,
Err(ref e) => self.transfer_owner(op(e))
}
}
#[inline]
pub fn unwrap_or(self, default: T) -> T {
match self.object {
Ok(t) => t,
Err(_) => default
}
}
#[inline]
pub fn unwrap_or_else<F: FnOnce(&E) -> T>(self, op: F) -> T {
match self.object {
Ok(t) => t,
Err(e) => op(&e),
}
}
#[inline]
pub unsafe fn unwrap_unchecked(self) -> T {
match self.object {
Ok(object) => object,
Err(_) => unsafe { unreachable_unchecked() },
}
}
#[inline]
pub unsafe fn unwrap_err_unchecked(self) -> E {
match self.object {
Ok(_) => unsafe { unreachable_unchecked() },
Err(err) => err
}
}
pub fn transfer_owner<'b, U>(&self, other: TreeResult<'b, U, E>) -> TreeResult<'a, U, E> {
TreeResult { tree: self.tree, owner: self.owner, object: other.object, p_life: self.p_life}
}
fn fail(&self, msg: &str, error: &dyn fmt::Debug) -> ! {
unsafe { (*self.tree).get_node(self.owner).unwrap_unchecked() }.post(Log::Panic(&format!("{msg}: {error:?}")));
println!("\n[RUST TRACE]");
panic!();
}
}
impl <'a, T, E> TreeResult<'a, &T, E> {
#[inline]
pub fn copied(self) -> TreeResult<'a, T, E>
where
T: Copy,
{ self.map(|&t| t) }
#[inline]
pub fn cloned(self) -> TreeResult<'a, T, E>
where
T: Clone,
{ self.map(|t| t.clone()) }
}
impl <'a, T, E> TreeResult<'a, &mut T, E> {
#[inline]
pub fn copied(self) -> TreeResult<'a, T, E>
where
T: Copy,
{ self.map(|&mut t| t) }
#[inline]
pub fn cloned(self) -> TreeResult<'a, T, E>
where
T: Clone,
{ self.map(|t| t.clone()) }
}
impl <'a, 'b, T, E> TreeResult<'a, TreeOption<'b, T>, E> {
#[inline]
pub fn transpose(self) -> TreeOption<'a, TreeResult<'a, T, E>> {
match self.object {
Ok(inner) => {
match inner.to_option() {
Some(x) => unsafe { TreeOption::new(self.tree, self.owner, Some(TreeResult::new(self.tree, self.owner, Ok(x)))) },
None => unsafe { TreeOption::new(self.tree, self.owner, None) },
}
},
Err(e) => unsafe { TreeOption::new(self.tree, self.owner, Some(TreeResult::new(self.tree, self.owner, Err(e)))) }
}
}
}
impl <'a, 'b, T, E> TreeResult<'a, TreeResult<'b, T, E>, E> {
#[inline]
pub fn flatten(self) -> TreeResult<'a, T, E> {
match self.object {
Ok(inner) => TreeResult { tree: self.tree, owner: self.owner, object: inner.to_result(), p_life: self.p_life },
Err(err) => TreeResult { tree: self.tree, owner: self.owner, object: Err(err), p_life: self.p_life }
}
}
}