aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2020-08-11 23:25:13 -0700
committerChih-Hung Hsieh <chh@google.com>2020-08-17 16:10:23 -0700
commit6f3fa15012d300a886add4bacbd8ad2267abee28 (patch)
tree3c6efb31bc3e28bdbfe31f8a2bebecc953aed3a5 /src
parentc2da9b8c19fae2731e052f8c4bbda9ad12452457 (diff)
downloadlazycell-6f3fa15012d300a886add4bacbd8ad2267abee28.tar.gz
Upgrade rust/crates/lazycell to 1.3.0
* Keep Android local change in src/lib.rs. // ANDROID: Unconditionally use std to allow building as a dylib. extern crate std; Change-Id: Iffb11ce26acde2ae512502957ac87b3e430fe673 Test: make
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs45
-rw-r--r--src/serde_impl.rs86
2 files changed, 125 insertions, 6 deletions
diff --git a/src/lib.rs b/src/lib.rs
index e753ea8..923d672 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,5 @@
// Original work Copyright (c) 2014 The Rust Project Developers
-// Modified work Copyright (c) 2016-2018 Nikita Pekin and the lazycell contributors
+// Modified work Copyright (c) 2016-2020 Nikita Pekin and the lazycell contributors
// See the README.md file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
@@ -44,9 +44,16 @@
//! coordination in a thread-safe fashion. The limitation of an `AtomicLazyCell`
//! is that after it is initialized, it can't be modified.
+
// ANDROID: Unconditionally use std to allow building as a dylib.
+#[cfg(not(test))]
#[macro_use]
extern crate std;
+#[cfg(feature = "serde")]
+extern crate serde;
+
+#[cfg(feature = "serde")]
+mod serde_impl;
use std::cell::UnsafeCell;
use std::mem;
@@ -57,7 +64,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
/// A `LazyCell` is completely frozen once filled, **unless** you have `&mut`
/// access to it, in which case `LazyCell::borrow_mut` may be used to mutate the
/// contents.
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct LazyCell<T> {
inner: UnsafeCell<Option<T>>,
}
@@ -70,12 +77,13 @@ impl<T> LazyCell<T> {
/// Put a value into this cell.
///
- /// This function will return `Err(value)` is the cell is already full.
+ /// This function will return `Err(value)` if the cell is already full.
pub fn fill(&self, value: T) -> Result<(), T> {
- let slot = unsafe { &mut *self.inner.get() };
+ let slot = unsafe { &*self.inner.get() };
if slot.is_some() {
return Err(value);
}
+ let slot = unsafe { &mut *self.inner.get() };
*slot = Some(value);
Ok(())
@@ -214,6 +222,12 @@ impl<T: Copy> LazyCell<T> {
}
}
+impl<T> Default for LazyCell<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl <T: Clone> Clone for LazyCell<T> {
/// Create a clone of this `LazyCell`
///
@@ -231,7 +245,7 @@ const LOCK: usize = 1;
const SOME: usize = 2;
/// A lazily filled and thread-safe `Cell`, with frozen contents.
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct AtomicLazyCell<T> {
inner: UnsafeCell<Option<T>>,
state: AtomicUsize,
@@ -251,7 +265,7 @@ impl<T> AtomicLazyCell<T> {
/// Put a value into this cell.
///
- /// This function will return `Err(value)` is the cell is already full.
+ /// This function will return `Err(value)` if the cell is already full.
pub fn fill(&self, t: T) -> Result<(), T> {
if NONE != self.state.compare_and_swap(NONE, LOCK, Ordering::Acquire) {
return Err(t);
@@ -324,6 +338,12 @@ impl<T: Copy> AtomicLazyCell<T> {
}
}
+impl<T> Default for AtomicLazyCell<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl<T: Clone> Clone for AtomicLazyCell<T> {
/// Create a clone of this `AtomicLazyCell`
///
@@ -645,4 +665,17 @@ mod tests {
assert_eq!(clone2.borrow(), Some(&4));
assert_eq!(cell.borrow(), Some(&2));
}
+
+ #[test]
+ fn default() {
+ #[derive(Default)]
+ struct Defaultable;
+ struct NonDefaultable;
+
+ let _: LazyCell<Defaultable> = LazyCell::default();
+ let _: LazyCell<NonDefaultable> = LazyCell::default();
+
+ let _: AtomicLazyCell<Defaultable> = AtomicLazyCell::default();
+ let _: AtomicLazyCell<NonDefaultable> = AtomicLazyCell::default();
+ }
}
diff --git a/src/serde_impl.rs b/src/serde_impl.rs
new file mode 100644
index 0000000..8f08f7b
--- /dev/null
+++ b/src/serde_impl.rs
@@ -0,0 +1,86 @@
+// Copyright (c) 2020 Nikita Pekin and the lazycell contributors
+// See the README.md file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.use serde::ser::{Serialize, Serializer};
+use serde::ser::{Serialize, Serializer};
+use serde::de::{self, Deserialize, Deserializer, Visitor};
+
+use std::fmt;
+use std::marker::PhantomData;
+
+use super::{LazyCell, AtomicLazyCell};
+
+impl<T: Serialize> Serialize for LazyCell<T> {
+ fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ match self.borrow() {
+ Some(val) => serializer.serialize_some(val),
+ None => serializer.serialize_none()
+ }
+ }
+}
+
+
+impl<T: Serialize> Serialize for AtomicLazyCell<T> {
+ fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ match self.borrow() {
+ Some(val) => serializer.serialize_some(val),
+ None => serializer.serialize_none()
+ }
+ }
+}
+
+struct LazyCellVisitor<T>(PhantomData<*const T>);
+impl<'de, T: Deserialize<'de>> Visitor<'de> for LazyCellVisitor<T> {
+ type Value = LazyCell<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a LazyCell")
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ let mut cell = LazyCell::new();
+ cell.replace(T::deserialize(deserializer)?);
+ Ok(cell)
+ }
+
+ fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
+ Ok(LazyCell::new())
+ }
+}
+
+impl<'de, T: Deserialize<'de>> Deserialize<'de> for LazyCell<T> {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_option(LazyCellVisitor(PhantomData))
+ }
+}
+
+
+struct AtomicLazyCellVisitor<T>(PhantomData<*const T>);
+impl<'de, T: Deserialize<'de>> Visitor<'de> for AtomicLazyCellVisitor<T> {
+ type Value = AtomicLazyCell<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("an AtomicLazyCell")
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ let mut cell = AtomicLazyCell::new();
+ cell.replace(T::deserialize(deserializer)?);
+ Ok(cell)
+ }
+
+ fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
+ Ok(AtomicLazyCell::new())
+ }
+}
+
+
+impl<'de, T: Deserialize<'de>> Deserialize<'de> for AtomicLazyCell<T> {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_option(AtomicLazyCellVisitor(PhantomData))
+ }
+}