aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--CHANGELOG.md19
-rw-r--r--Cargo.toml8
-rw-r--r--Cargo.toml.orig3
-rw-r--r--METADATA6
-rw-r--r--README.md3
-rw-r--r--src/lib.rs45
-rw-r--r--src/serde_impl.rs86
8 files changed, 158 insertions, 14 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index ff846a0..09afcb8 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "db9289a32df4ba3b1de8c383b68b342be4a8a1ba"
+ "sha1": "b78f3f10c0d005b81d97011fd7f98fc3cdff5982"
}
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33f1a7d..1ac4a6e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+<a name="v1.3.0"></a>
+## v1.3.0 (2020-08-12)
+
+
+#### Bug Fixes
+
+* Add custom `impl Default` to support non-Default-able `<T>` types ([b49f4eab](https://github.com/indiv0/lazycell/commit/b49f4eabec49c0a5146ef01017c2506a3c357180))
+* **lazycell:** Fix unsound aliasing in `LazyCell::fill` ([e789ac1a](https://github.com/indiv0/lazycell/commit/e789ac1a99010ad79c2d09c761fec6d67053647d), closes [#98](https://github.com/indiv0/lazycell/issues/98))
+
+#### Features
+
+* Implement serde support ([e728a0b6](https://github.com/indiv0/lazycell/commit/e728a0b680e607b793a81b5af7bf7f1d2c0eb5e5))
+
+#### Documentation
+
+* fix typo ([5f5ba9d5](https://github.com/indiv0/lazycell/commit/5f5ba9d5ac3364f8376c0c872c2e5094974385ba))
+
+
+
<a name="v1.2.1"></a>
## v1.2.1 (2018-12-03)
diff --git a/Cargo.toml b/Cargo.toml
index faecd45..fce4dd5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
@@ -12,7 +12,7 @@
[package]
name = "lazycell"
-version = "1.2.1"
+version = "1.3.0"
authors = ["Alex Crichton <alex@alexcrichton.com>", "Nikita Pekin <contact@nikitapek.in>"]
include = ["CHANGELOG.md", "Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "README.md", "src/**/*.rs"]
description = "A library providing a lazily filled Cell struct"
@@ -25,6 +25,10 @@ repository = "https://github.com/indiv0/lazycell"
version = "0.0"
optional = true
+[dependencies.serde]
+version = "^1"
+optional = true
+
[features]
nightly = []
nightly-testing = ["clippy", "nightly"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 5a4d935..3fc95b6 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "lazycell"
-version = "1.2.1"
+version = "1.3.0"
authors = ["Alex Crichton <alex@alexcrichton.com>",
"Nikita Pekin <contact@nikitapek.in>"]
description = "A library providing a lazily filled Cell struct"
@@ -20,6 +20,7 @@ include = [
[dependencies]
clippy = { version = "0.0", optional = true }
+serde = { version = "^1", optional = true }
[features]
nightly = []
diff --git a/METADATA b/METADATA
index 6cd979d..f1ef45b 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/indiv0/lazycell"
}
- version: "1.2.1"
+ version: "1.3.0"
license_type: NOTICE
last_upgrade_date {
year: 2020
- month: 3
- day: 31
+ month: 8
+ day: 11
}
}
diff --git a/README.md b/README.md
index 4e1dd99..555fe39 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@
</tr>
<tr>
<td colspan="2">
+ <a href="https://crates.io/crates/lazycell" title="Crates.io downloads"><img src="https://img.shields.io/crates/d/lazycell.svg" alt="cargo-downloads-badge"></img></a>
<a href="https://indiv0.github.io/lazycell/lazycell" title="API Docs"><img src="https://img.shields.io/badge/API-docs-blue.svg" alt="api-docs-badge"></img></a>
<a href="https://crates.io/crates/lazycell" title="Crates.io"><img src="https://img.shields.io/crates/v/lazycell.svg" alt="crates-io"></img></a>
<a href="#license" title="License: MIT/Apache-2.0"><img src="https://img.shields.io/crates/l/lazycell.svg" alt="license-badge"></img></a>
@@ -30,7 +31,7 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
-lazycell = "1.2"
+lazycell = "1.3"
```
And in your `lib.rs` or `main.rs`:
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))
+ }
+}