tc_state/object/
instance.rs1use std::convert::{TryFrom, TryInto};
4use std::fmt;
5use std::marker::PhantomData;
6use std::ops::Deref;
7
8use log::debug;
9use safecast::TryCastFrom;
10
11use tc_scalar::Scalar;
12use tc_transact::public::ToState;
13use tc_transact::{Gateway, Transaction};
14use tc_value::Value;
15use tcgeneric::Map;
16
17use crate::{CacheBlock, State};
18
19use super::{InstanceClass, Object};
20
21pub struct InstanceExt<Txn, T> {
23 parent: Box<T>,
24 class: InstanceClass,
25 members: Map<State<Txn>>,
26 txn: PhantomData<Txn>, }
28
29impl<Txn, T> Clone for InstanceExt<Txn, T>
30where
31 T: Clone,
32{
33 fn clone(&self) -> Self {
34 Self {
35 parent: self.parent.clone(),
36 class: self.class.clone(),
37 members: self.members.clone(),
38 txn: self.txn,
39 }
40 }
41}
42
43impl<Txn, T> InstanceExt<Txn, T>
44where
45 T: tcgeneric::Instance,
46{
47 pub fn new(parent: T, class: InstanceClass) -> Self {
49 InstanceExt {
50 parent: Box::new(parent),
51 class,
52 members: Map::default(),
53 txn: PhantomData,
54 }
55 }
56
57 pub fn anonymous(parent: T, class: InstanceClass, members: Map<State<Txn>>) -> Self {
59 InstanceExt {
60 parent: Box::new(parent),
61 class,
62 members,
63 txn: PhantomData,
64 }
65 }
66
67 pub fn members(&self) -> &Map<State<Txn>> {
69 &self.members
70 }
71
72 pub fn parent(&self) -> &T {
74 &self.parent
75 }
76
77 pub fn proto(&self) -> &Map<Scalar> {
79 self.class.proto()
80 }
81
82 pub fn try_into<E, O: tcgeneric::Instance + TryFrom<T, Error = E>>(
84 self,
85 ) -> Result<InstanceExt<Txn, O>, E> {
86 let class = self.class;
87 let parent = (*self.parent).try_into()?;
88
89 Ok(InstanceExt {
90 parent: Box::new(parent),
91 class,
92 members: self.members,
93 txn: self.txn,
94 })
95 }
96}
97
98impl<Txn, T> tcgeneric::Instance for InstanceExt<Txn, T>
99where
100 Txn: Send + Sync,
101 T: tcgeneric::Instance,
102{
103 type Class = InstanceClass;
104
105 fn class(&self) -> Self::Class {
106 self.class.clone()
107 }
108}
109
110impl<Txn, T> Deref for InstanceExt<Txn, T>
111where
112 T: tcgeneric::Instance,
113{
114 type Target = T;
115
116 fn deref(&self) -> &Self::Target {
117 &self.parent
118 }
119}
120
121impl<Txn, T> TryCastFrom<InstanceExt<Txn, T>> for Scalar
122where
123 T: fmt::Debug,
124 Scalar: TryCastFrom<T>,
125{
126 fn can_cast_from(instance: &InstanceExt<Txn, T>) -> bool {
127 debug!("Scalar::can_cast_from {:?}?", instance);
128 Self::can_cast_from(&(*instance).parent)
129 }
130
131 fn opt_cast_from(instance: InstanceExt<Txn, T>) -> Option<Self> {
132 Self::opt_cast_from(*instance.parent)
133 }
134}
135
136impl<Txn, T> TryCastFrom<InstanceExt<Txn, T>> for Value
137where
138 T: fmt::Debug,
139 Value: TryCastFrom<T>,
140{
141 fn can_cast_from(instance: &InstanceExt<Txn, T>) -> bool {
142 debug!("Value::can_cast_from {:?}?", instance);
143 Self::can_cast_from(&(*instance).parent)
144 }
145
146 fn opt_cast_from(instance: InstanceExt<Txn, T>) -> Option<Self> {
147 Self::opt_cast_from(*instance.parent)
148 }
149}
150
151impl<Txn, T> ToState<State<Txn>> for InstanceExt<Txn, T>
152where
153 Txn: Transaction<CacheBlock> + Gateway<State<Txn>>,
154 T: tcgeneric::Instance + ToState<State<Txn>>,
155{
156 fn to_state(&self) -> State<Txn> {
157 let instance = InstanceExt {
158 parent: Box::new(self.parent.to_state()),
159 class: self.class.clone(),
160 members: self.members.clone(),
161 txn: self.txn,
162 };
163
164 State::Object(Object::Instance(instance))
165 }
166}
167
168impl<Txn, T> fmt::Debug for InstanceExt<Txn, T> {
169 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170 write!(f, "instance of {}", std::any::type_name::<T>())
171 }
172}