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

@ -11,6 +11,7 @@ default = ["nightly"]
nightly = ["smallvec/const_generics"] nightly = ["smallvec/const_generics"]
[dependencies] [dependencies]
cfg-if = "1.0.0"
color-eyre = {version = "0.5.10", default-features=false} color-eyre = {version = "0.5.10", default-features=false}
cryptohelpers = {version = "1.7.1", features=["full"]} cryptohelpers = {version = "1.7.1", features=["full"]}
difference = "2.0.0" difference = "2.0.0"
@ -25,6 +26,7 @@ pretty_env_logger = "0.4.0"
serde = {version = "1.0.118", features=["derive"]} serde = {version = "1.0.118", features=["derive"]}
sha2 = "0.9.2" sha2 = "0.9.2"
smallvec = {version = "1.6.0", features= ["union", "serde", "write"]} smallvec = {version = "1.6.0", features= ["union", "serde", "write"]}
smolset = "1.1.0"
tokio = {version = "0.2", features=["full"] } tokio = {version = "0.2", features=["full"] }
uuid = {version = "0.8.1", features=["v4","serde"]} uuid = {version = "0.8.1", features=["v4","serde"]}
warp = "0.2.5" 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 lazy_static;
#[macro_use] extern crate log; #[macro_use] extern crate log;
#[macro_use] extern crate mopa; #[macro_use] extern crate mopa;
#[macro_use] extern crate cfg_if;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use color_eyre::{ use color_eyre::{

@ -15,7 +15,7 @@ use crate::service::{
use std::{error, fmt}; use std::{error, fmt};
use std::sync::Weak; use std::sync::Weak;
use std::any::Any; use std::any::Any;
use std::collections::BTreeMap; use std::collections::{BTreeMap};
id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages"); id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages");
@ -80,36 +80,16 @@ pub(super) struct Supervisor
/// Object sent through the broadcast channel. /// Object sent through the broadcast channel.
/// ///
/// These objects can be cloned and downcasted, but can also be atomically refcounted if that is more desireable. /// These objects can be cloned and downcasted, becaause they are atomically refcounted if that is more desireable.
/// #[derive(Clone)]
/// # Cloning pub struct ServiceEventObject(Arc<dyn Any + Send + Sync + 'static>);
/// 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>);
shim_debug!(ServiceEventObject); shim_debug!(ServiceEventObject);
/// A weak reference to a `ServiceEventObject`. /// A weak reference to a `ServiceEventObject`.
#[derive(Clone)] #[derive(Clone)]
pub struct ServiceEventObjectRef(Weak<dyn AnyCloneable + Send + Sync + 'static>); pub struct ServiceEventObjectRef(Weak<dyn Any + Send + Sync + 'static>);
shim_debug!(ServiceEventObjectRef); 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 impl ServiceEventObjectRef
{ {
/// Try to upgrade to a concrete reference, and then clone the inner object. /// Try to upgrade to a concrete reference, and then clone the inner object.
@ -135,12 +115,6 @@ impl ServiceEventObjectRef
impl ServiceEventObject 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. /// Get a weak reference counted handle to the object, without cloning the object itself.
pub fn clone_weak(&self) -> ServiceEventObjectRef pub fn clone_weak(&self) -> ServiceEventObjectRef
{ {
@ -164,8 +138,11 @@ impl ServiceEventObject
{ {
match Arc::downcast(self.0) match Arc::downcast(self.0)
{ {
Ok(v) => v, Ok(v) => match Arc::try_unwrap(v) {
Err(e) => Self(e), 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 /// 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 /// Try to downcast the object into a concrete type
#[inline] pub fn downcast_ref<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T> #[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, 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 /// An event outputted from a state service's broadcast stream
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ServiceEvent pub struct ServiceEvent
{ {
kind: ServiceEventKind, kind: ServiceEventKind,
directed: Option<MaybeVec<ServiceSubID>>, directed: Option<SESet<ServiceSubID>>,
obj: Option<EventObjectRefCloneWrap>, obj: Option<ServiceEventObject>,
} }
impl ServiceEvent impl ServiceEvent
@ -220,7 +207,7 @@ impl ServiceEvent
pub fn is_directed_for(&self, whom: &ServiceSubID) -> bool pub fn is_directed_for(&self, whom: &ServiceSubID) -> bool
{ {
if let Some(yes) = self.directed.as_ref() { if let Some(yes) = self.directed.as_ref() {
yes == whom yes.contains(whom)
} else { } else {
false false
} }
@ -234,25 +221,25 @@ impl ServiceEvent
/// Check who this event is directed to. /// Check who this event is directed to.
/// ///
/// If it is not directed, an empty slice will be returned. /// 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() match self.directed.as_ref()
{ {
Some(yes) => &yes[..], Some(yes) => MaybeIter::many(yes.iter()),
None => &[], None => MaybeIter::none(),
} }
} }
/// Get a reference to the object, if there is one. /// Get a reference to the object, if there is one.
pub fn obj_ref(&self) -> Option<&ServiceEventObject> 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. /// Get a mutable reference to the object, if there is one.
pub fn obj_mut(&mut self) -> Option<&mut ServiceEventObject> 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. /// 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> impl From<ServiceEvent> for Option<ServiceEventObject>
{ {
#[inline] fn from(from: ServiceEvent) -> Self #[inline] fn from(from: ServiceEvent) -> Self
@ -282,7 +270,7 @@ impl TryFrom<ServiceEvent> for ServiceEventObject
{ {
match from.obj match from.obj
{ {
Some(obj) => Ok(obj.0), Some(obj) => Ok(obj),
None => Err(NoObjectError), None => Err(NoObjectError),
} }
} }

Loading…
Cancel
Save