rune/runtime/value/
rtti.rs1use core::borrow::Borrow;
2use core::cmp::Ordering;
3use core::hash;
4
5#[cfg(feature = "musli")]
6use musli::{Decode, Encode};
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use crate::alloc::prelude::*;
11use crate::alloc::HashMap;
12use crate::item::Item;
13use crate::runtime::{FieldMap, TypeInfo, Value};
14use crate::sync::Arc;
15use crate::{Hash, ItemBuf};
16
17#[doc(hidden)]
19pub struct Accessor<'a> {
20 pub(crate) fields: &'a HashMap<Box<str>, usize>,
21 pub(crate) data: &'a [Value],
22}
23
24impl Accessor<'_> {
25 #[doc(hidden)]
27 pub fn get<Q>(&self, key: &Q) -> Option<&Value>
28 where
29 Box<str>: Borrow<Q>,
30 Q: hash::Hash + Eq + ?Sized,
31 {
32 self.data.get(*self.fields.get(key)?)
33 }
34}
35
36#[derive(Debug, Clone, Copy)]
38#[cfg_attr(
39 feature = "serde",
40 derive(Serialize, Deserialize),
41 serde(rename_all = "kebab-case")
42)]
43#[cfg_attr(feature = "musli", derive(Encode, Decode))]
44pub(crate) enum RttiKind {
45 Empty,
47 Tuple,
49 Struct,
51}
52
53#[derive(Debug)]
55#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
56#[cfg_attr(feature = "musli", derive(Encode, Decode))]
57#[non_exhaustive]
58pub struct Rtti {
59 pub(crate) kind: RttiKind,
61 pub(crate) hash: Hash,
63 pub(crate) variant_hash: Hash,
65 pub(crate) item: ItemBuf,
67 pub(crate) fields: FieldMap<Box<str>, usize>,
69}
70
71impl Rtti {
72 #[inline]
74 pub(crate) fn is(&self, hash: Hash, variant_hash: Hash) -> bool {
75 self.hash == hash && self.variant_hash == variant_hash
76 }
77
78 #[inline]
80 pub fn item(&self) -> &Item {
81 &self.item
82 }
83
84 #[inline]
86 pub fn type_hash(&self) -> Hash {
87 self.hash
88 }
89
90 #[inline]
92 pub fn type_info(this: Arc<Self>) -> TypeInfo {
93 TypeInfo::rtti(this)
94 }
95}
96
97impl PartialEq for Rtti {
98 fn eq(&self, other: &Self) -> bool {
99 self.hash == other.hash && self.variant_hash == other.variant_hash
100 }
101}
102
103impl Eq for Rtti {}
104
105impl hash::Hash for Rtti {
106 fn hash<H: hash::Hasher>(&self, state: &mut H) {
107 self.hash.hash(state);
108 self.variant_hash.hash(state);
109 }
110}
111
112impl PartialOrd for Rtti {
113 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
114 Some(self.cmp(other))
115 }
116}
117
118impl Ord for Rtti {
119 #[inline]
120 fn cmp(&self, other: &Self) -> Ordering {
121 self.hash
122 .cmp(&other.hash)
123 .then_with(|| self.variant_hash.cmp(&other.variant_hash))
124 }
125}