Skip to content

Commit

Permalink
Implement BorshSerialize/BoshDeserialize for interior mutability stdl…
Browse files Browse the repository at this point in the history
…ib types

It's basically the same as the serde implementations from 5 years ago
serde-rs/serde#882 .
  • Loading branch information
Fuuzetsu committed Dec 7, 2023
1 parent 2b1f6c9 commit 451fe35
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
41 changes: 41 additions & 0 deletions borsh/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,47 @@ impl<T: ?Sized> BorshDeserialize for PhantomData<T> {
Ok(PhantomData)
}
}

#[cfg(feature = "std")]
impl<T> BorshDeserialize for core::cell::Cell<T>
where
T: BorshDeserialize,
{
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
<T as BorshDeserialize>::deserialize_reader(reader).map(core::cell::Cell::new)
}
}

#[cfg(feature = "std")]
impl<T> BorshDeserialize for core::cell::RefCell<T>
where
T: BorshDeserialize,
{
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
<T as BorshDeserialize>::deserialize_reader(reader).map(core::cell::RefCell::new)
}
}

#[cfg(feature = "std")]
impl<T> BorshDeserialize for std::sync::Mutex<T>
where
T: BorshDeserialize,
{
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
<T as BorshDeserialize>::deserialize_reader(reader).map(std::sync::Mutex::new)
}
}

#[cfg(feature = "std")]
impl<T> BorshDeserialize for std::sync::RwLock<T>
where
T: BorshDeserialize,
{
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
<T as BorshDeserialize>::deserialize_reader(reader).map(std::sync::RwLock::new)
}
}

/// Deserializes an object from a slice of bytes.
/// # Example
/// ```
Expand Down
52 changes: 52 additions & 0 deletions borsh/src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,55 @@ impl<T: ?Sized> BorshSerialize for PhantomData<T> {
Ok(())
}
}

#[cfg(feature = "std")]
impl<T> BorshSerialize for core::cell::Cell<T>
where
T: BorshSerialize + Copy,
{
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
<T as BorshSerialize>::serialize(&self.get(), writer)
}
}

#[cfg(feature = "std")]
impl<T> BorshSerialize for core::cell::RefCell<T>
where
T: BorshSerialize,
{
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
<T as BorshSerialize>::serialize(core::ops::Deref::deref(&self.borrow()), writer)
}
}

#[cfg(feature = "std")]
impl<T> BorshSerialize for std::sync::Mutex<T>
where
T: BorshSerialize,
{
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
match self.lock().as_deref() {
Ok(locked) => <T as BorshSerialize>::serialize(locked, writer),
Err(_) => Err(Error::new(
ErrorKind::InvalidData,
"lock poison error while serializing",
)),
}
}
}

#[cfg(feature = "std")]
impl<T> BorshSerialize for std::sync::RwLock<T>
where
T: BorshSerialize,
{
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
match self.read().as_deref() {
Ok(locked) => <T as BorshSerialize>::serialize(locked, writer),
Err(_) => Err(Error::new(
ErrorKind::InvalidData,
"lock poison error while serializing",
)),
}
}
}

0 comments on commit 451fe35

Please sign in to comment.