更新libclamav库1.0.0版本
This commit is contained in:
680
clamav/libclamav_rust/.cargo/vendor/lazycell/src/lib.rs
vendored
Normal file
680
clamav/libclamav_rust/.cargo/vendor/lazycell/src/lib.rs
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
// Original work Copyright (c) 2014 The Rust Project Developers
|
||||
// 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
|
||||
// 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.
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(feature = "nightly", feature(plugin))]
|
||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||
|
||||
//! This crate provides a `LazyCell` struct which acts as a lazily filled
|
||||
//! `Cell`.
|
||||
//!
|
||||
//! With a `RefCell`, the inner contents cannot be borrowed for the lifetime of
|
||||
//! the entire object, but only of the borrows returned. A `LazyCell` is a
|
||||
//! variation on `RefCell` which allows borrows to be tied to the lifetime of
|
||||
//! the outer object.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! The following example shows a quick example of the basic functionality of
|
||||
//! `LazyCell`.
|
||||
//!
|
||||
//! ```
|
||||
//! use lazycell::LazyCell;
|
||||
//!
|
||||
//! let lazycell = LazyCell::new();
|
||||
//!
|
||||
//! assert_eq!(lazycell.borrow(), None);
|
||||
//! assert!(!lazycell.filled());
|
||||
//! lazycell.fill(1).ok();
|
||||
//! assert!(lazycell.filled());
|
||||
//! assert_eq!(lazycell.borrow(), Some(&1));
|
||||
//! assert_eq!(lazycell.into_inner(), Some(1));
|
||||
//! ```
|
||||
//!
|
||||
//! `AtomicLazyCell` is a variant that uses an atomic variable to manage
|
||||
//! coordination in a thread-safe fashion. The limitation of an `AtomicLazyCell`
|
||||
//! is that after it is initialized, it can't be modified.
|
||||
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[macro_use]
|
||||
extern crate core as std;
|
||||
#[cfg(feature = "serde")]
|
||||
extern crate serde;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde_impl;
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
use std::mem;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
/// A lazily filled `Cell`, with mutable contents.
|
||||
///
|
||||
/// 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)]
|
||||
pub struct LazyCell<T> {
|
||||
inner: UnsafeCell<Option<T>>,
|
||||
}
|
||||
|
||||
impl<T> LazyCell<T> {
|
||||
/// Creates a new, empty, `LazyCell`.
|
||||
pub fn new() -> LazyCell<T> {
|
||||
LazyCell { inner: UnsafeCell::new(None) }
|
||||
}
|
||||
|
||||
/// Put a value into this cell.
|
||||
///
|
||||
/// This function will return `Err(value)` if the cell is already full.
|
||||
pub fn fill(&self, value: T) -> Result<(), T> {
|
||||
let slot = unsafe { &*self.inner.get() };
|
||||
if slot.is_some() {
|
||||
return Err(value);
|
||||
}
|
||||
let slot = unsafe { &mut *self.inner.get() };
|
||||
*slot = Some(value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put a value into this cell.
|
||||
///
|
||||
/// Note that this function is infallible but requires `&mut self`. By
|
||||
/// requiring `&mut self` we're guaranteed that no active borrows to this
|
||||
/// cell can exist so we can always fill in the value. This may not always
|
||||
/// be usable, however, as `&mut self` may not be possible to borrow.
|
||||
///
|
||||
/// # Return value
|
||||
///
|
||||
/// This function returns the previous value, if any.
|
||||
pub fn replace(&mut self, value: T) -> Option<T> {
|
||||
mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
|
||||
}
|
||||
|
||||
/// Test whether this cell has been previously filled.
|
||||
pub fn filled(&self) -> bool {
|
||||
self.borrow().is_some()
|
||||
}
|
||||
|
||||
/// Borrows the contents of this lazy cell for the duration of the cell
|
||||
/// itself.
|
||||
///
|
||||
/// This function will return `Some` if the cell has been previously
|
||||
/// initialized, and `None` if it has not yet been initialized.
|
||||
pub fn borrow(&self) -> Option<&T> {
|
||||
unsafe { &*self.inner.get() }.as_ref()
|
||||
}
|
||||
|
||||
/// Borrows the contents of this lazy cell mutably for the duration of the cell
|
||||
/// itself.
|
||||
///
|
||||
/// This function will return `Some` if the cell has been previously
|
||||
/// initialized, and `None` if it has not yet been initialized.
|
||||
pub fn borrow_mut(&mut self) -> Option<&mut T> {
|
||||
unsafe { &mut *self.inner.get() }.as_mut()
|
||||
}
|
||||
|
||||
/// Borrows the contents of this lazy cell for the duration of the cell
|
||||
/// itself.
|
||||
///
|
||||
/// If the cell has not yet been filled, the cell is first filled using the
|
||||
/// function provided.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the cell becomes filled as a side effect of `f`.
|
||||
pub fn borrow_with<F: FnOnce() -> T>(&self, f: F) -> &T {
|
||||
if let Some(value) = self.borrow() {
|
||||
return value;
|
||||
}
|
||||
let value = f();
|
||||
if self.fill(value).is_err() {
|
||||
panic!("borrow_with: cell was filled by closure")
|
||||
}
|
||||
self.borrow().unwrap()
|
||||
}
|
||||
|
||||
/// Borrows the contents of this `LazyCell` mutably for the duration of the
|
||||
/// cell itself.
|
||||
///
|
||||
/// If the cell has not yet been filled, the cell is first filled using the
|
||||
/// function provided.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the cell becomes filled as a side effect of `f`.
|
||||
pub fn borrow_mut_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
|
||||
if !self.filled() {
|
||||
let value = f();
|
||||
if self.fill(value).is_err() {
|
||||
panic!("borrow_mut_with: cell was filled by closure")
|
||||
}
|
||||
}
|
||||
|
||||
self.borrow_mut().unwrap()
|
||||
}
|
||||
|
||||
/// Same as `borrow_with`, but allows the initializing function to fail.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the cell becomes filled as a side effect of `f`.
|
||||
pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
|
||||
where F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
if let Some(value) = self.borrow() {
|
||||
return Ok(value);
|
||||
}
|
||||
let value = f()?;
|
||||
if self.fill(value).is_err() {
|
||||
panic!("try_borrow_with: cell was filled by closure")
|
||||
}
|
||||
Ok(self.borrow().unwrap())
|
||||
}
|
||||
|
||||
/// Same as `borrow_mut_with`, but allows the initializing function to fail.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the cell becomes filled as a side effect of `f`.
|
||||
pub fn try_borrow_mut_with<E, F>(&mut self, f: F) -> Result<&mut T, E>
|
||||
where F: FnOnce() -> Result<T, E>
|
||||
{
|
||||
if self.filled() {
|
||||
return Ok(self.borrow_mut().unwrap());
|
||||
}
|
||||
let value = f()?;
|
||||
if self.fill(value).is_err() {
|
||||
panic!("try_borrow_mut_with: cell was filled by closure")
|
||||
}
|
||||
Ok(self.borrow_mut().unwrap())
|
||||
}
|
||||
|
||||
/// Consumes this `LazyCell`, returning the underlying value.
|
||||
pub fn into_inner(self) -> Option<T> {
|
||||
// Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
|
||||
// function. This unsafe can be removed when supporting Rust older than
|
||||
// 1.25 is not needed.
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe { self.inner.into_inner() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> LazyCell<T> {
|
||||
/// Returns a copy of the contents of the lazy cell.
|
||||
///
|
||||
/// This function will return `Some` if the cell has been previously initialized,
|
||||
/// and `None` if it has not yet been initialized.
|
||||
pub fn get(&self) -> Option<T> {
|
||||
unsafe { *self.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for LazyCell<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl <T: Clone> Clone for LazyCell<T> {
|
||||
/// Create a clone of this `LazyCell`
|
||||
///
|
||||
/// If self has not been initialized, returns an uninitialized `LazyCell`
|
||||
/// otherwise returns a `LazyCell` already initialized with a clone of the
|
||||
/// contents of self.
|
||||
fn clone(&self) -> LazyCell<T> {
|
||||
LazyCell { inner: UnsafeCell::new(self.borrow().map(Clone::clone) ) }
|
||||
}
|
||||
}
|
||||
|
||||
// Tracks the AtomicLazyCell inner state
|
||||
const NONE: usize = 0;
|
||||
const LOCK: usize = 1;
|
||||
const SOME: usize = 2;
|
||||
|
||||
/// A lazily filled and thread-safe `Cell`, with frozen contents.
|
||||
#[derive(Debug)]
|
||||
pub struct AtomicLazyCell<T> {
|
||||
inner: UnsafeCell<Option<T>>,
|
||||
state: AtomicUsize,
|
||||
}
|
||||
|
||||
impl<T> AtomicLazyCell<T> {
|
||||
/// An empty `AtomicLazyCell`.
|
||||
pub const NONE: Self = Self {
|
||||
inner: UnsafeCell::new(None),
|
||||
state: AtomicUsize::new(NONE),
|
||||
};
|
||||
|
||||
/// Creates a new, empty, `AtomicLazyCell`.
|
||||
pub fn new() -> AtomicLazyCell<T> {
|
||||
Self::NONE
|
||||
}
|
||||
|
||||
/// Put a value into this cell.
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
|
||||
unsafe { *self.inner.get() = Some(t) };
|
||||
|
||||
if LOCK != self.state.compare_and_swap(LOCK, SOME, Ordering::Release) {
|
||||
panic!("unable to release lock");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put a value into this cell.
|
||||
///
|
||||
/// Note that this function is infallible but requires `&mut self`. By
|
||||
/// requiring `&mut self` we're guaranteed that no active borrows to this
|
||||
/// cell can exist so we can always fill in the value. This may not always
|
||||
/// be usable, however, as `&mut self` may not be possible to borrow.
|
||||
///
|
||||
/// # Return value
|
||||
///
|
||||
/// This function returns the previous value, if any.
|
||||
pub fn replace(&mut self, value: T) -> Option<T> {
|
||||
match mem::replace(self.state.get_mut(), SOME) {
|
||||
NONE | SOME => {}
|
||||
_ => panic!("cell in inconsistent state"),
|
||||
}
|
||||
mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
|
||||
}
|
||||
|
||||
/// Test whether this cell has been previously filled.
|
||||
pub fn filled(&self) -> bool {
|
||||
self.state.load(Ordering::Acquire) == SOME
|
||||
}
|
||||
|
||||
/// Borrows the contents of this lazy cell for the duration of the cell
|
||||
/// itself.
|
||||
///
|
||||
/// This function will return `Some` if the cell has been previously
|
||||
/// initialized, and `None` if it has not yet been initialized.
|
||||
pub fn borrow(&self) -> Option<&T> {
|
||||
match self.state.load(Ordering::Acquire) {
|
||||
SOME => unsafe { &*self.inner.get() }.as_ref(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes this `LazyCell`, returning the underlying value.
|
||||
pub fn into_inner(self) -> Option<T> {
|
||||
// Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
|
||||
// function. This unsafe can be removed when supporting Rust older than
|
||||
// 1.25 is not needed.
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe { self.inner.into_inner() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> AtomicLazyCell<T> {
|
||||
/// Returns a copy of the contents of the lazy cell.
|
||||
///
|
||||
/// This function will return `Some` if the cell has been previously initialized,
|
||||
/// and `None` if it has not yet been initialized.
|
||||
pub fn get(&self) -> Option<T> {
|
||||
match self.state.load(Ordering::Acquire) {
|
||||
SOME => unsafe { *self.inner.get() },
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for AtomicLazyCell<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for AtomicLazyCell<T> {
|
||||
/// Create a clone of this `AtomicLazyCell`
|
||||
///
|
||||
/// If self has not been initialized, returns an uninitialized `AtomicLazyCell`
|
||||
/// otherwise returns an `AtomicLazyCell` already initialized with a clone of the
|
||||
/// contents of self.
|
||||
fn clone(&self) -> AtomicLazyCell<T> {
|
||||
self.borrow().map_or(
|
||||
Self::NONE,
|
||||
|v| AtomicLazyCell {
|
||||
inner: UnsafeCell::new(Some(v.clone())),
|
||||
state: AtomicUsize::new(SOME),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Sync + Send> Sync for AtomicLazyCell<T> {}
|
||||
|
||||
unsafe impl<T: Send> Send for AtomicLazyCell<T> {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{AtomicLazyCell, LazyCell};
|
||||
|
||||
#[test]
|
||||
fn test_borrow_from_empty() {
|
||||
let lazycell: LazyCell<usize> = LazyCell::new();
|
||||
|
||||
let value = lazycell.borrow();
|
||||
assert_eq!(value, None);
|
||||
|
||||
let value = lazycell.get();
|
||||
assert_eq!(value, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fill_and_borrow() {
|
||||
let lazycell = LazyCell::new();
|
||||
|
||||
assert!(!lazycell.filled());
|
||||
lazycell.fill(1).unwrap();
|
||||
assert!(lazycell.filled());
|
||||
|
||||
let value = lazycell.borrow();
|
||||
assert_eq!(value, Some(&1));
|
||||
|
||||
let value = lazycell.get();
|
||||
assert_eq!(value, Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_mut() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
assert!(lazycell.borrow_mut().is_none());
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
assert_eq!(lazycell.borrow_mut(), Some(&mut 1));
|
||||
|
||||
*lazycell.borrow_mut().unwrap() = 2;
|
||||
assert_eq!(lazycell.borrow_mut(), Some(&mut 2));
|
||||
|
||||
// official way to reset the cell
|
||||
lazycell = LazyCell::new();
|
||||
assert!(lazycell.borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_already_filled_error() {
|
||||
let lazycell = LazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
assert_eq!(lazycell.fill(1), Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_with() {
|
||||
let lazycell = LazyCell::new();
|
||||
|
||||
let value = lazycell.borrow_with(|| 1);
|
||||
assert_eq!(&1, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_with_already_filled() {
|
||||
let lazycell = LazyCell::new();
|
||||
lazycell.fill(1).unwrap();
|
||||
|
||||
let value = lazycell.borrow_with(|| 1);
|
||||
assert_eq!(&1, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_with_not_called_when_filled() {
|
||||
let lazycell = LazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
|
||||
let value = lazycell.borrow_with(|| 2);
|
||||
assert_eq!(&1, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_borrow_with_sound_with_reentrancy() {
|
||||
// Kudos to dbaupp for discovering this issue
|
||||
// https://www.reddit.com/r/rust/comments/5vs9rt/lazycell_a_rust_library_providing_a_lazilyfilled/de527xm/
|
||||
let lazycell: LazyCell<Box<i32>> = LazyCell::new();
|
||||
|
||||
let mut reference: Option<&i32> = None;
|
||||
|
||||
lazycell.borrow_with(|| {
|
||||
let _ = lazycell.fill(Box::new(1));
|
||||
reference = lazycell.borrow().map(|r| &**r);
|
||||
Box::new(2)
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_mut_with() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
|
||||
{
|
||||
let value = lazycell.borrow_mut_with(|| 1);
|
||||
assert_eq!(&mut 1, value);
|
||||
*value = 2;
|
||||
}
|
||||
assert_eq!(&2, lazycell.borrow().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_mut_with_already_filled() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
lazycell.fill(1).unwrap();
|
||||
|
||||
let value = lazycell.borrow_mut_with(|| 1);
|
||||
assert_eq!(&1, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_mut_with_not_called_when_filled() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
|
||||
let value = lazycell.borrow_mut_with(|| 2);
|
||||
assert_eq!(&1, value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_with_ok() {
|
||||
let lazycell = LazyCell::new();
|
||||
let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
|
||||
assert_eq!(result, Ok(&1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_with_err() {
|
||||
let lazycell = LazyCell::<()>::new();
|
||||
let result = lazycell.try_borrow_with(|| Err(1));
|
||||
assert_eq!(result, Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_with_already_filled() {
|
||||
let lazycell = LazyCell::new();
|
||||
lazycell.fill(1).unwrap();
|
||||
let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
|
||||
assert_eq!(result, Ok(&1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_try_borrow_with_sound_with_reentrancy() {
|
||||
let lazycell: LazyCell<Box<i32>> = LazyCell::new();
|
||||
|
||||
let mut reference: Option<&i32> = None;
|
||||
|
||||
let _ = lazycell.try_borrow_with::<(), _>(|| {
|
||||
let _ = lazycell.fill(Box::new(1));
|
||||
reference = lazycell.borrow().map(|r| &**r);
|
||||
Ok(Box::new(2))
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_mut_with_ok() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
{
|
||||
let result = lazycell.try_borrow_mut_with::<(), _>(|| Ok(1));
|
||||
assert_eq!(result, Ok(&mut 1));
|
||||
*result.unwrap() = 2;
|
||||
}
|
||||
assert_eq!(&mut 2, lazycell.borrow().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_mut_with_err() {
|
||||
let mut lazycell = LazyCell::<()>::new();
|
||||
let result = lazycell.try_borrow_mut_with(|| Err(1));
|
||||
assert_eq!(result, Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_borrow_mut_with_already_filled() {
|
||||
let mut lazycell = LazyCell::new();
|
||||
lazycell.fill(1).unwrap();
|
||||
let result = lazycell.try_borrow_mut_with::<(), _>(|| unreachable!());
|
||||
assert_eq!(result, Ok(&mut 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_inner() {
|
||||
let lazycell = LazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
let value = lazycell.into_inner();
|
||||
assert_eq!(value, Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_borrow_from_empty() {
|
||||
let lazycell: AtomicLazyCell<usize> = AtomicLazyCell::new();
|
||||
|
||||
let value = lazycell.borrow();
|
||||
assert_eq!(value, None);
|
||||
|
||||
let value = lazycell.get();
|
||||
assert_eq!(value, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_fill_and_borrow() {
|
||||
let lazycell = AtomicLazyCell::new();
|
||||
|
||||
assert!(!lazycell.filled());
|
||||
lazycell.fill(1).unwrap();
|
||||
assert!(lazycell.filled());
|
||||
|
||||
let value = lazycell.borrow();
|
||||
assert_eq!(value, Some(&1));
|
||||
|
||||
let value = lazycell.get();
|
||||
assert_eq!(value, Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_already_filled_panic() {
|
||||
let lazycell = AtomicLazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
assert_eq!(1, lazycell.fill(1).unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atomic_into_inner() {
|
||||
let lazycell = AtomicLazyCell::new();
|
||||
|
||||
lazycell.fill(1).unwrap();
|
||||
let value = lazycell.into_inner();
|
||||
assert_eq!(value, Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normal_replace() {
|
||||
let mut cell = LazyCell::new();
|
||||
assert_eq!(cell.fill(1), Ok(()));
|
||||
assert_eq!(cell.replace(2), Some(1));
|
||||
assert_eq!(cell.replace(3), Some(2));
|
||||
assert_eq!(cell.borrow(), Some(&3));
|
||||
|
||||
let mut cell = LazyCell::new();
|
||||
assert_eq!(cell.replace(2), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atomic_replace() {
|
||||
let mut cell = AtomicLazyCell::new();
|
||||
assert_eq!(cell.fill(1), Ok(()));
|
||||
assert_eq!(cell.replace(2), Some(1));
|
||||
assert_eq!(cell.replace(3), Some(2));
|
||||
assert_eq!(cell.borrow(), Some(&3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone() {
|
||||
let mut cell = LazyCell::new();
|
||||
let clone1 = cell.clone();
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(cell.fill(1), Ok(()));
|
||||
let mut clone2 = cell.clone();
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(clone2.borrow(), Some(&1));
|
||||
assert_eq!(cell.replace(2), Some(1));
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(clone2.borrow(), Some(&1));
|
||||
assert_eq!(clone1.fill(3), Ok(()));
|
||||
assert_eq!(clone2.replace(4), Some(1));
|
||||
assert_eq!(clone1.borrow(), Some(&3));
|
||||
assert_eq!(clone2.borrow(), Some(&4));
|
||||
assert_eq!(cell.borrow(), Some(&2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_atomic() {
|
||||
let mut cell = AtomicLazyCell::new();
|
||||
let clone1 = cell.clone();
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(cell.fill(1), Ok(()));
|
||||
let mut clone2 = cell.clone();
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(clone2.borrow(), Some(&1));
|
||||
assert_eq!(cell.replace(2), Some(1));
|
||||
assert_eq!(clone1.borrow(), None);
|
||||
assert_eq!(clone2.borrow(), Some(&1));
|
||||
assert_eq!(clone1.fill(3), Ok(()));
|
||||
assert_eq!(clone2.replace(4), Some(1));
|
||||
assert_eq!(clone1.borrow(), Some(&3));
|
||||
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();
|
||||
}
|
||||
}
|
86
clamav/libclamav_rust/.cargo/vendor/lazycell/src/serde_impl.rs
vendored
Normal file
86
clamav/libclamav_rust/.cargo/vendor/lazycell/src/serde_impl.rs
vendored
Normal file
@@ -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))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user