allow arbitrary attribute value in owned attribute value (#574)
This commit is contained in:
1 parent
e98f46bbcc
commit
928b5358b2
4 files changed
+92
-4
No files matched your search
@@ -45,6 +45,9 @@ serde = { version = "1", features = ["derive"], optional = true }
|
||||
# todo: I want to get rid of this
|
||||
backtrace = "0.3"
|
||||
|
||||
# allows cloing trait objects
|
||||
dyn-clone = "1.0.9"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
serialize = ["serde"]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::fmt::Formatter;
|
||||
|
||||
use dyn_clone::{clone_box, DynClone};
|
||||
|
||||
/// Possible values for an attribute
|
||||
// trying to keep values at 3 bytes
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
@@ -74,8 +76,8 @@ impl<'a> std::fmt::Display for AttributeValue<'a> {
|
||||
#[derive(Clone, Copy)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct ArbitraryAttributeValue<'a> {
|
||||
pub value: &'a dyn std::any::Any,
|
||||
pub cmp: fn(&'a dyn std::any::Any, &'a dyn std::any::Any) -> bool,
|
||||
pub value: &'a dyn AnyClone,
|
||||
pub cmp: fn(&dyn AnyClone, &dyn AnyClone) -> bool,
|
||||
}
|
||||
|
||||
impl PartialEq for ArbitraryAttributeValue<'_> {
|
||||
@@ -118,6 +120,79 @@ impl<'de, 'a> serde::Deserialize<'de> for ArbitraryAttributeValue<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A clone, sync and send version of `Any`
|
||||
// we only need the Sync + Send bound when hot reloading is enabled
|
||||
#[cfg(any(feature = "hot-reload", debug_assertions))]
|
||||
pub trait AnyClone: std::any::Any + DynClone + Send + Sync {
|
||||
fn as_any(&self) -> &dyn std::any::Any;
|
||||
}
|
||||
#[cfg(not(any(feature = "hot-reload", debug_assertions)))]
|
||||
pub trait AnyClone: std::any::Any + DynClone {
|
||||
fn as_any(&self) -> &dyn std::any::Any;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "hot-reload", debug_assertions))]
|
||||
impl<T: std::any::Any + DynClone + Send + Sync> AnyClone for T {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(feature = "hot-reload", debug_assertions)))]
|
||||
impl<T: std::any::Any + DynClone> AnyClone for T {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
dyn_clone::clone_trait_object!(AnyClone);
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct OwnedArbitraryAttributeValue {
|
||||
pub value: Box<dyn AnyClone>,
|
||||
pub cmp: fn(&dyn AnyClone, &dyn AnyClone) -> bool,
|
||||
}
|
||||
|
||||
impl PartialEq for OwnedArbitraryAttributeValue {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(self.cmp)(&*self.value, &*other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for OwnedArbitraryAttributeValue {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("OwnedArbitraryAttributeValue").finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'a> serde::Serialize for OwnedArbitraryAttributeValue {
|
||||
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
panic!("OwnedArbitraryAttributeValue should not be serialized")
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'de, 'a> serde::Deserialize<'de> for &'a OwnedArbitraryAttributeValue {
|
||||
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
panic!("OwnedArbitraryAttributeValue is not deserializable!")
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'de, 'a> serde::Deserialize<'de> for OwnedArbitraryAttributeValue {
|
||||
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
panic!("OwnedArbitraryAttributeValue is not deserializable!")
|
||||
}
|
||||
}
|
||||
|
||||
// todo
|
||||
#[allow(missing_docs)]
|
||||
impl<'a> AttributeValue<'a> {
|
||||
@@ -261,7 +336,7 @@ pub enum OwnedAttributeValue {
|
||||
|
||||
Bytes(Vec<u8>),
|
||||
// TODO: support other types
|
||||
// Any(ArbitraryAttributeValue<'a>),
|
||||
Any(OwnedArbitraryAttributeValue),
|
||||
}
|
||||
|
||||
impl PartialEq<AttributeValue<'_>> for OwnedAttributeValue {
|
||||
@@ -321,7 +396,10 @@ impl<'a> From<AttributeValue<'a>> for OwnedAttributeValue {
|
||||
OwnedAttributeValue::Vec4Uint(f1, f2, f3, f4)
|
||||
}
|
||||
AttributeValue::Bytes(b) => OwnedAttributeValue::Bytes(b.to_owned()),
|
||||
AttributeValue::Any(_) => todo!(),
|
||||
AttributeValue::Any(a) => OwnedAttributeValue::Any(OwnedArbitraryAttributeValue {
|
||||
value: clone_box(a.value),
|
||||
cmp: a.cmp,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,6 +790,12 @@ impl TemplateValue for OwnedAttributeValue {
|
||||
OwnedAttributeValue::Vec4Uint(u1, u2, u3, u4) => {
|
||||
AttributeValue::Vec4Uint(u1, u2, u3, u4)
|
||||
}
|
||||
OwnedAttributeValue::Any(owned) => {
|
||||
AttributeValue::Any(crate::ArbitraryAttributeValue {
|
||||
value: bump.alloc(owned.value),
|
||||
cmp: owned.cmp,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,7 @@ impl ToTokens for TemplateAttributeBuilder {
|
||||
OwnedAttributeValue::Bytes(b) => {
|
||||
quote! {StaticAttributeValue::Bytes(&[#(#b),*])}
|
||||
}
|
||||
OwnedAttributeValue::Any(_) => todo!(),
|
||||
};
|
||||
quote! {TemplateAttributeValue::Static(#val)}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user