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
|
# todo: I want to get rid of this
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
|
|
||||||
|
# allows cloing trait objects
|
||||||
|
dyn-clone = "1.0.9"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
serialize = ["serde"]
|
serialize = ["serde"]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
|
use dyn_clone::{clone_box, DynClone};
|
||||||
|
|
||||||
/// Possible values for an attribute
|
/// Possible values for an attribute
|
||||||
// trying to keep values at 3 bytes
|
// trying to keep values at 3 bytes
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
@@ -74,8 +76,8 @@ impl<'a> std::fmt::Display for AttributeValue<'a> {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct ArbitraryAttributeValue<'a> {
|
pub struct ArbitraryAttributeValue<'a> {
|
||||||
pub value: &'a dyn std::any::Any,
|
pub value: &'a dyn AnyClone,
|
||||||
pub cmp: fn(&'a dyn std::any::Any, &'a dyn std::any::Any) -> bool,
|
pub cmp: fn(&dyn AnyClone, &dyn AnyClone) -> bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ArbitraryAttributeValue<'_> {
|
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
|
// todo
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
impl<'a> AttributeValue<'a> {
|
impl<'a> AttributeValue<'a> {
|
||||||
@@ -261,7 +336,7 @@ pub enum OwnedAttributeValue {
|
|||||||
|
|
||||||
Bytes(Vec<u8>),
|
Bytes(Vec<u8>),
|
||||||
// TODO: support other types
|
// TODO: support other types
|
||||||
// Any(ArbitraryAttributeValue<'a>),
|
Any(OwnedArbitraryAttributeValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<AttributeValue<'_>> for OwnedAttributeValue {
|
impl PartialEq<AttributeValue<'_>> for OwnedAttributeValue {
|
||||||
@@ -321,7 +396,10 @@ impl<'a> From<AttributeValue<'a>> for OwnedAttributeValue {
|
|||||||
OwnedAttributeValue::Vec4Uint(f1, f2, f3, f4)
|
OwnedAttributeValue::Vec4Uint(f1, f2, f3, f4)
|
||||||
}
|
}
|
||||||
AttributeValue::Bytes(b) => OwnedAttributeValue::Bytes(b.to_owned()),
|
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) => {
|
OwnedAttributeValue::Vec4Uint(u1, u2, u3, u4) => {
|
||||||
AttributeValue::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) => {
|
OwnedAttributeValue::Bytes(b) => {
|
||||||
quote! {StaticAttributeValue::Bytes(&[#(#b),*])}
|
quote! {StaticAttributeValue::Bytes(&[#(#b),*])}
|
||||||
}
|
}
|
||||||
|
OwnedAttributeValue::Any(_) => todo!(),
|
||||||
};
|
};
|
||||||
quote! {TemplateAttributeValue::Static(#val)}
|
quote! {TemplateAttributeValue::Static(#val)}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user