rune/runtime/value/
rtti.rsuse core::borrow::Borrow;
use core::cmp::Ordering;
use core::hash;
use rust_alloc::sync::Arc;
use serde::{Deserialize, Serialize};
use crate::alloc::prelude::*;
use crate::alloc::HashMap;
use crate::item::Item;
use crate::runtime::{FieldMap, TypeInfo, Value};
use crate::{Hash, ItemBuf};
#[doc(hidden)]
pub struct Accessor<'a> {
pub(crate) fields: &'a HashMap<Box<str>, usize>,
pub(crate) data: &'a [Value],
}
impl<'a> Accessor<'a> {
#[doc(hidden)]
pub fn get<Q>(&self, key: &Q) -> Option<&Value>
where
Box<str>: Borrow<Q>,
Q: hash::Hash + Eq + ?Sized,
{
self.data.get(*self.fields.get(key)?)
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub(crate) enum RttiKind {
Empty,
Tuple,
Struct,
}
#[derive(Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Rtti {
pub(crate) kind: RttiKind,
pub(crate) hash: Hash,
pub(crate) variant_hash: Hash,
pub(crate) item: ItemBuf,
pub(crate) fields: FieldMap<Box<str>, usize>,
}
impl Rtti {
#[inline]
pub(crate) fn is(&self, hash: Hash, variant_hash: Hash) -> bool {
self.hash == hash && self.variant_hash == variant_hash
}
#[inline]
pub fn item(&self) -> &Item {
&self.item
}
#[inline]
pub fn type_hash(&self) -> Hash {
self.hash
}
#[inline]
pub fn type_info(self: Arc<Self>) -> TypeInfo {
TypeInfo::rtti(self)
}
}
impl PartialEq for Rtti {
fn eq(&self, other: &Self) -> bool {
self.hash == other.hash && self.variant_hash == other.variant_hash
}
}
impl Eq for Rtti {}
impl hash::Hash for Rtti {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.hash.hash(state);
self.variant_hash.hash(state);
}
}
impl PartialOrd for Rtti {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Rtti {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.hash
.cmp(&other.hash)
.then_with(|| self.variant_hash.cmp(&other.variant_hash))
}
}