builds with non-clone 'any'

another-service-failure
Avril 4 years ago
parent 13cb323ed3
commit 925770fbeb
Signed by: flanchan
GPG Key ID: 284488987C31F630

11
Cargo.lock generated

@ -1368,6 +1368,15 @@ dependencies = [
"serde",
]
[[package]]
name = "smolset"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5a73542b3021a40b49f29e6ce18b65ff38dbafbf7df8be0fa9f9305305f62ee"
dependencies = [
"smallvec",
]
[[package]]
name = "socket2"
version = "0.3.19"
@ -1779,6 +1788,7 @@ dependencies = [
name = "yuurei"
version = "0.1.0"
dependencies = [
"cfg-if 1.0.0",
"color-eyre",
"cryptohelpers",
"difference",
@ -1793,6 +1803,7 @@ dependencies = [
"serde",
"sha2",
"smallvec",
"smolset",
"tokio",
"uuid",
"warp",

@ -11,6 +11,7 @@ default = ["nightly"]
nightly = ["smallvec/const_generics"]
[dependencies]
cfg-if = "1.0.0"
color-eyre = {version = "0.5.10", default-features=false}
cryptohelpers = {version = "1.7.1", features=["full"]}
difference = "2.0.0"
@ -25,6 +26,7 @@ pretty_env_logger = "0.4.0"
serde = {version = "1.0.118", features=["derive"]}
sha2 = "0.9.2"
smallvec = {version = "1.6.0", features= ["union", "serde", "write"]}
smolset = "1.1.0"
tokio = {version = "0.2", features=["full"] }
uuid = {version = "0.8.1", features=["v4","serde"]}
warp = "0.2.5"

@ -578,3 +578,80 @@ impl Clone for DynCloneable
}
mod maybe_iter
{
#[derive(Debug, Clone)]
enum Inner<I, T>
{
Some(I),
One(std::iter::Once<T>),
None,
}
/// An iterator that may yield 0, 1, or more values.
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct MaybeIter<I, T>(Inner<I, T>);
impl<I, T> MaybeIter<I, T>
where I: Iterator<Item=T>
{
/// Create a single element iterator
pub fn one<U: Into<T>>(from: U) -> Self
{
Self(Inner::One(std::iter::once(from.into())))
}
/// Create a new instance from an iterator
pub fn many<U: IntoIterator<IntoIter = I, Item=T>>(from: U) -> Self
{
Self(Inner::Some(from.into_iter()))
}
/// Create a new instance that yields 0 items
#[inline(always)] pub fn none() -> Self
{
Self(Inner::None)
}
}
impl<I, T, U> From<Option<U>> for MaybeIter<I, T>
where I: Iterator<Item=T>,
U: IntoIterator<IntoIter=I, Item=T>
{
fn from(from: Option<U>) -> Self
{
match from {
Some(many) => Self::many(many),
_ => Self::none()
}
}
}
impl<I, T> Iterator for MaybeIter<I, T>
where I: Iterator<Item=T>
{
type Item = T;
fn next(&mut self) -> Option<Self::Item>
{
match &mut self.0 {
Inner::Some(x) => x.next(),
Inner::One(x) => x.next(),
Inner::None => None,
}
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0
{
Inner::One(c) => c.size_hint(),
Inner::Some(x) => x.size_hint(),
Inner::None => (0, Some(0))
}
}
}
impl<T, I: Iterator<Item=T>> std::iter::FusedIterator for MaybeIter<I, T>
where I: std::iter::FusedIterator{}
impl<T, I: Iterator<Item=T>> ExactSizeIterator for MaybeIter<I, T>
where I: ExactSizeIterator{}
}
pub use maybe_iter::MaybeIter;

@ -8,6 +8,7 @@
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate mopa;
#[macro_use] extern crate cfg_if;
use std::convert::{TryFrom, TryInto};
use color_eyre::{

@ -15,7 +15,7 @@ use crate::service::{
use std::{error, fmt};
use std::sync::Weak;
use std::any::Any;
use std::collections::BTreeMap;
use std::collections::{BTreeMap};
id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages");
@ -80,36 +80,16 @@ pub(super) struct Supervisor
/// Object sent through the broadcast channel.
///
/// These objects can be cloned and downcasted, but can also be atomically refcounted if that is more desireable.
///
/// # Cloning
/// The implementation of `Clone` for this instance clones the inner object, not the refcount. Use `clone_ref()` to *just* clone the refcount.
/// To downcast and clone the inner object without an extra `Arc` allocation, use `downcast_clone()` or `downcast().map(Clone::clone)`.
pub struct ServiceEventObject(Arc<dyn AnyCloneable + Send + Sync + 'static>);
/// These objects can be cloned and downcasted, becaause they are atomically refcounted if that is more desireable.
#[derive(Clone)]
pub struct ServiceEventObject(Arc<dyn Any + Send + Sync + 'static>);
shim_debug!(ServiceEventObject);
/// A weak reference to a `ServiceEventObject`.
#[derive(Clone)]
pub struct ServiceEventObjectRef(Weak<dyn AnyCloneable + Send + Sync + 'static>);
pub struct ServiceEventObjectRef(Weak<dyn Any + Send + Sync + 'static>);
shim_debug!(ServiceEventObjectRef);
/// Wrapper used when broadcasting to prevent useless inner object clones.
#[derive(Debug)]
struct EventObjectRefCloneWrap(ServiceEventObject);
impl Clone for EventObjectRefCloneWrap
{
fn clone(&self) -> Self {
Self(self.0.clone_ref())
}
}
impl Clone for ServiceEventObject
{
fn clone(&self) -> Self {
Self(Arc::from(self.0.as_ref().clone_dyn()))
}
}
impl ServiceEventObjectRef
{
/// Try to upgrade to a concrete reference, and then clone the inner object.
@ -135,12 +115,6 @@ impl ServiceEventObjectRef
impl ServiceEventObject
{
/// Get an owned reference counted handle to the object, without cloning the object itself.
pub fn clone_ref(&self) -> Self
{
Self(Arc::clone(&self.0))
}
/// Get a weak reference counted handle to the object, without cloning the object itself.
pub fn clone_weak(&self) -> ServiceEventObjectRef
{
@ -164,8 +138,11 @@ impl ServiceEventObject
{
match Arc::downcast(self.0)
{
Ok(v) => v,
Err(e) => Self(e),
Ok(v) => match Arc::try_unwrap(v) {
Ok(v) => Ok(v),
Err(s) => Err(Self(s)),
},
Err(e) => Err(Self(e)),
}
}
@ -176,14 +153,14 @@ impl ServiceEventObject
}
/// Try to downcast the object into a concrete type
#[inline] pub fn is<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T>
#[inline] pub fn is<T: AnyCloneable + Send + Sync + 'static>(&self) -> bool
{
self.0.is()
self.0.as_ref().is::<T>()
}
/// Try to downcast the object into a concrete type
#[inline] pub fn downcast_ref<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T>
{
self.0.downcast_ref()
self.0.as_ref().downcast_ref::<T>()
}
}
@ -199,13 +176,23 @@ pub enum ServiceEventKind
KeepAlive,
}
cfg_if!{
if #[cfg(debug_assertions)] {
/// Type used for directed array.
/// Currently testing `smolset` over eagerly allocating.
type SESet<T> = smolset::SmolSet<[T; 1]>;
} else {
type SESet<T> = std::collections::HashSet<T>;
}
}
/// An event outputted from a state service's broadcast stream
#[derive(Debug, Clone)]
pub struct ServiceEvent
{
kind: ServiceEventKind,
directed: Option<MaybeVec<ServiceSubID>>,
obj: Option<EventObjectRefCloneWrap>,
directed: Option<SESet<ServiceSubID>>,
obj: Option<ServiceEventObject>,
}
impl ServiceEvent
@ -220,7 +207,7 @@ impl ServiceEvent
pub fn is_directed_for(&self, whom: &ServiceSubID) -> bool
{
if let Some(yes) = self.directed.as_ref() {
yes == whom
yes.contains(whom)
} else {
false
}
@ -234,25 +221,25 @@ impl ServiceEvent
/// Check who this event is directed to.
///
/// If it is not directed, an empty slice will be returned.
pub fn directed_to(&self) -> &[&ServiceSubID]
pub fn directed_to(&self) -> impl Iterator<Item = &'_ ServiceSubID> + '_
{
match self.directed.as_ref()
{
Some(yes) => &yes[..],
None => &[],
Some(yes) => MaybeIter::many(yes.iter()),
None => MaybeIter::none(),
}
}
/// Get a reference to the object, if there is one.
pub fn obj_ref(&self) -> Option<&ServiceEventObject>
{
self.obj.as_ref().map(|x| x.0)
self.obj.as_ref()
}
/// Get a mutable reference to the object, if there is one.
pub fn obj_mut(&mut self) -> Option<&mut ServiceEventObject>
{
self.obj.as_mut().map(|x| x.0)
self.obj.as_mut()
}
/// Try to consume into the inner object. If there is no object, return self.
@ -266,6 +253,7 @@ impl ServiceEvent
}
}
impl From<ServiceEvent> for Option<ServiceEventObject>
{
#[inline] fn from(from: ServiceEvent) -> Self
@ -282,7 +270,7 @@ impl TryFrom<ServiceEvent> for ServiceEventObject
{
match from.obj
{
Some(obj) => Ok(obj.0),
Some(obj) => Ok(obj),
None => Err(NoObjectError),
}
}

Loading…
Cancel
Save