diff options
author | Haibo Huang <hhb@google.com> | 2020-08-18 01:24:07 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-08-18 01:24:07 +0000 |
commit | f994c4f69af435e7c6f296513a8ce0726c22c86e (patch) | |
tree | 3c6efb31bc3e28bdbfe31f8a2bebecc953aed3a5 | |
parent | ac198d3d80dfd9d479fbede80f796f5cad7cc89c (diff) | |
parent | 6f3fa15012d300a886add4bacbd8ad2267abee28 (diff) | |
download | lazycell-f994c4f69af435e7c6f296513a8ce0726c22c86e.tar.gz |
Upgrade rust/crates/lazycell to 1.3.0 am: 6f3fa15012
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/lazycell/+/1397967
Change-Id: I98f934ae1c669879eff93bc37125956d8c439c84
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | CHANGELOG.md | 19 | ||||
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | Cargo.toml.orig | 3 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/lib.rs | 45 | ||||
-rw-r--r-- | src/serde_impl.rs | 86 |
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) @@ -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 = [] @@ -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 } } @@ -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`: @@ -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)) + } +} |