track caller for easier debugging

This commit is contained in:
niedzwiedzw committed 2023-07-12 01:19:20 +02:00
1 parent f159779af4
commit 43e3304eaf
1 file changed
+14 -2
+14 -2
View File
@@ -2,6 +2,7 @@ use dioxus_core::{ScopeId, ScopeState};
use std::{ use std::{
cell::{Ref, RefCell, RefMut}, cell::{Ref, RefCell, RefMut},
collections::HashSet, collections::HashSet,
panic::Location,
rc::Rc, rc::Rc,
sync::Arc, sync::Arc,
}; };
@@ -123,15 +124,17 @@ pub struct UseSharedState<T> {
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum UseSharedStateError { pub enum UseSharedStateError {
#[error("{type_name} is already borrowed, so it cannot be borrowed mutably.")] #[error("[{caller}] {type_name} is already borrowed, so it cannot be borrowed mutably.")]
AlreadyBorrowed { AlreadyBorrowed {
source: core::cell::BorrowMutError, source: core::cell::BorrowMutError,
type_name: &'static str, type_name: &'static str,
caller: &'static Location<'static>,
}, },
#[error("{type_name} is already borrowed mutably, so it cannot be borrowed anymore.")] #[error("[caller] {type_name} is already borrowed mutably, so it cannot be borrowed anymore.")]
AlreadyBorrowedMutably { AlreadyBorrowedMutably {
source: core::cell::BorrowError, source: core::cell::BorrowError,
type_name: &'static str, type_name: &'static str,
caller: &'static Location<'static>,
}, },
} }
@@ -144,17 +147,20 @@ impl<T> UseSharedState<T> {
} }
/// Try reading the shared state /// Try reading the shared state
#[track_caller]
pub fn try_read(&self) -> UseSharedStateResult<Ref<'_, T>> { pub fn try_read(&self) -> UseSharedStateResult<Ref<'_, T>> {
self.inner self.inner
.try_borrow() .try_borrow()
.map_err(|source| UseSharedStateError::AlreadyBorrowedMutably { .map_err(|source| UseSharedStateError::AlreadyBorrowedMutably {
source, source,
type_name: std::any::type_name::<Self>(), type_name: std::any::type_name::<Self>(),
caller: Location::caller(),
}) })
.map(|value| Ref::map(value, |inner| &inner.value)) .map(|value| Ref::map(value, |inner| &inner.value))
} }
/// Read the shared value /// Read the shared value
#[track_caller]
pub fn read(&self) -> Ref<'_, T> { pub fn read(&self) -> Ref<'_, T> {
match self.try_read() { match self.try_read() {
Ok(value) => value, Ok(value) => value,
@@ -166,12 +172,14 @@ impl<T> UseSharedState<T> {
} }
/// Try writing the shared state /// Try writing the shared state
#[track_caller]
pub fn try_write(&self) -> UseSharedStateResult<RefMut<'_, T>> { pub fn try_write(&self) -> UseSharedStateResult<RefMut<'_, T>> {
self.inner self.inner
.try_borrow_mut() .try_borrow_mut()
.map_err(|source| UseSharedStateError::AlreadyBorrowed { .map_err(|source| UseSharedStateError::AlreadyBorrowed {
source, source,
type_name: std::any::type_name::<Self>(), type_name: std::any::type_name::<Self>(),
caller: Location::caller(),
}) })
.map(|mut value| { .map(|mut value| {
value.notify_consumers(); value.notify_consumers();
@@ -183,6 +191,7 @@ impl<T> UseSharedState<T> {
/// ///
/// ///
// TODO: We prevent unncessary notifications only in the hook, but we should figure out some more global lock // TODO: We prevent unncessary notifications only in the hook, but we should figure out some more global lock
#[track_caller]
pub fn write(&self) -> RefMut<'_, T> { pub fn write(&self) -> RefMut<'_, T> {
match self.try_write() { match self.try_write() {
Ok(value) => value, Ok(value) => value,
@@ -194,17 +203,20 @@ impl<T> UseSharedState<T> {
} }
/// Tries writing the value without forcing a re-render /// Tries writing the value without forcing a re-render
#[track_caller]
pub fn try_write_silent(&self) -> UseSharedStateResult<RefMut<'_, T>> { pub fn try_write_silent(&self) -> UseSharedStateResult<RefMut<'_, T>> {
self.inner self.inner
.try_borrow_mut() .try_borrow_mut()
.map_err(|source| UseSharedStateError::AlreadyBorrowed { .map_err(|source| UseSharedStateError::AlreadyBorrowed {
source, source,
type_name: std::any::type_name::<Self>(), type_name: std::any::type_name::<Self>(),
caller: Location::caller(),
}) })
.map(|value| RefMut::map(value, |inner| &mut inner.value)) .map(|value| RefMut::map(value, |inner| &mut inner.value))
} }
/// Writes the value without forcing a re-render /// Writes the value without forcing a re-render
#[track_caller]
pub fn write_silent(&self) -> RefMut<'_, T> { pub fn write_silent(&self) -> RefMut<'_, T> {
match self.try_write_silent() { match self.try_write_silent() {
Ok(value) => value, Ok(value) => value,