sim_lib_skill/
transport.rs1use std::sync::Arc;
2
3use sim_citizen_derive::non_citizen;
4use sim_kernel::{Cx, Expr, Object, ObjectCompat, Result, Symbol, Value};
5
6use crate::SkillCard;
7
8pub trait SkillEventSink {
10 fn emit(&mut self, cx: &mut Cx, event: Value) -> Result<()>;
12}
13
14pub trait SkillTransport: Send + Sync {
23 fn id(&self) -> &str;
25 fn kind(&self) -> &str;
27 fn discover(&self, cx: &mut Cx) -> Result<Vec<SkillCard>>;
29 fn call(
34 &self,
35 cx: &mut Cx,
36 card: &SkillCard,
37 args: Value,
38 events: Option<&mut dyn SkillEventSink>,
39 ) -> Result<Value>;
40 fn health(&self, cx: &mut Cx) -> Result<Value>;
42}
43
44#[derive(Clone)]
50#[non_citizen(
51 reason = "live skill transport handle; transport metadata is carried by skill/Card descriptor",
52 kind = "handle"
53)]
54pub struct SkillTransportValue {
55 transport: Arc<dyn SkillTransport>,
56}
57
58impl SkillTransportValue {
59 pub fn new(transport: Arc<dyn SkillTransport>) -> Self {
61 Self { transport }
62 }
63
64 pub fn transport(&self) -> Arc<dyn SkillTransport> {
66 self.transport.clone()
67 }
68}
69
70impl Object for SkillTransportValue {
71 fn display(&self, _cx: &mut Cx) -> Result<String> {
72 Ok(format!(
73 "#<skill-transport {}:{}>",
74 self.transport.kind(),
75 self.transport.id()
76 ))
77 }
78
79 fn as_any(&self) -> &dyn std::any::Any {
80 self
81 }
82}
83
84impl ObjectCompat for SkillTransportValue {
85 fn as_expr(&self, cx: &mut Cx) -> Result<Expr> {
86 self.as_table(cx)?.object().as_expr(cx)
87 }
88
89 fn as_table(&self, cx: &mut Cx) -> Result<Value> {
90 cx.factory().table(vec![
91 (
92 Symbol::new("kind"),
93 cx.factory().symbol(Symbol::new("skill/transport"))?,
94 ),
95 (
96 Symbol::new("id"),
97 cx.factory().string(self.transport.id().to_owned())?,
98 ),
99 (
100 Symbol::new("transport-kind"),
101 cx.factory().string(self.transport.kind().to_owned())?,
102 ),
103 ])
104 }
105}
106
107pub fn skill_transport_value(cx: &mut Cx, transport: Arc<dyn SkillTransport>) -> Result<Value> {
109 cx.factory()
110 .opaque(Arc::new(SkillTransportValue::new(transport)))
111}