tari_template_lib/component/
manager.rs1use serde::{de::DeserializeOwned, Serialize};
24use tari_bor::{from_value, to_value};
25use tari_template_abi::{call_engine, EngineOp};
26use tari_template_lib_types::{bytes::Bytes, TemplateAddress};
27
28use crate::{
29 args::{CallAction, CallInvokeArg, CallMethodArg, ComponentAction, ComponentInvokeArg, ComponentRef, InvokeResult},
30 auth::ComponentAccessRules,
31 caller_context::CallerContext,
32 models::ComponentAddress,
33};
34
35pub struct ComponentManager {
37 address: ComponentAddress,
38}
39
40impl ComponentManager {
41 pub(crate) fn new(address: ComponentAddress) -> Self {
43 Self { address }
44 }
45
46 pub fn get(address: ComponentAddress) -> Self {
48 Self { address }
49 }
50
51 pub fn current() -> Self {
54 Self::new(CallerContext::current_component_address())
55 }
56
57 pub fn call<T: Into<String>, R: DeserializeOwned, B: Into<Bytes>>(&self, method: T, args: Vec<B>) -> R {
61 self.call_internal(CallMethodArg {
62 component_address: self.address,
63 method: method.into(),
64 args: args.into_iter().map(Into::into).collect(),
65 })
66 }
67
68 fn call_internal<T: DeserializeOwned>(&self, arg: CallMethodArg) -> T {
69 let result = call_engine::<_, InvokeResult>(EngineOp::CallInvoke, &CallInvokeArg {
70 action: CallAction::CallMethod,
71 args: invoke_args![arg],
72 });
73
74 result
75 .decode()
76 .expect("failed to decode component call result from engine")
77 }
78
79 pub fn invoke<T: Into<String>, B: Into<Bytes>>(&self, method: T, args: Vec<B>) {
82 self.call(method, args)
83 }
84
85 pub fn get_state<T: DeserializeOwned>(&self) -> T {
87 let result = call_engine::<_, InvokeResult>(EngineOp::ComponentInvoke, &ComponentInvokeArg {
88 component_ref: ComponentRef::Ref(self.address),
89 action: ComponentAction::GetState,
90 args: invoke_args![],
91 });
92
93 let component: tari_bor::Value = result.decode().expect("failed to decode component state from engine");
94 from_value(&component).expect("Failed to decode component state")
95 }
96
97 pub fn set_state<T: Serialize>(&self, state: T) {
99 let state = to_value(&state).expect("Failed to encode component state");
100 let _result = call_engine::<_, InvokeResult>(EngineOp::ComponentInvoke, &ComponentInvokeArg {
101 component_ref: ComponentRef::Ref(self.address),
102 action: ComponentAction::SetState,
103 args: invoke_args![state],
104 });
105 }
106
107 pub fn set_access_rules(&self, access_rules: ComponentAccessRules) {
110 call_engine::<_, InvokeResult>(EngineOp::ComponentInvoke, &ComponentInvokeArg {
111 component_ref: ComponentRef::Ref(self.address),
112 action: ComponentAction::SetAccessRules,
113 args: invoke_args![access_rules],
114 });
115 }
116
117 pub fn get_template_address(&self) -> TemplateAddress {
119 let result = call_engine::<_, InvokeResult>(EngineOp::ComponentInvoke, &ComponentInvokeArg {
120 component_ref: ComponentRef::Ref(self.address),
121 action: ComponentAction::GetTemplateAddress,
122 args: invoke_args![],
123 });
124
125 result
126 .decode()
127 .expect("failed to decode component template address from engine")
128 }
129
130 pub fn component_address(&self) -> ComponentAddress {
131 self.address
132 }
133}