allow arbitrary attribute value in owned attribute value (#574)

This commit is contained in:
Demonthos authored and GitHub committed 2022-10-02 14:13:06 -07:00
1 parent e98f46bbcc
commit 928b5358b2
4 files changed
+92 -4

No files matched your search

+3
View File
@@ -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"]
+82 -4
View File
@@ -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,
}),
}
}
}
+6
View File
@@ -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,
})
}
}
}
}
+1
View File
@@ -216,6 +216,7 @@ impl ToTokens for TemplateAttributeBuilder {
OwnedAttributeValue::Bytes(b) => {
quote! {StaticAttributeValue::Bytes(&[#(#b),*])}
}
OwnedAttributeValue::Any(_) => todo!(),
};
quote! {TemplateAttributeValue::Static(#val)}
}