sim_lib_sequence/
profile.rs1use std::sync::Arc;
2
3use sim_kernel::{
4 CORE_SEQUENCE_CLASS_ID, ClassRef, Cx, Object, ObjectCompat, Result, Sequence, SequenceItem,
5 Symbol, Value, seq_close_value, seq_is_done, seq_next_value, seq_peek,
6};
7
8#[sim_citizen_derive::non_citizen(
9 reason = "profile sequence adapter; reconstruct from the profile symbol and source sequence descriptor",
10 kind = "handle",
11 descriptor = "core/Sequence"
12)]
13pub struct ProfileSequence {
19 profile: Symbol,
20 inner: Value,
21}
22
23impl ProfileSequence {
24 pub fn new(profile: Symbol, inner: Value) -> Self {
26 Self { profile, inner }
27 }
28
29 pub fn profile(&self) -> &Symbol {
31 &self.profile
32 }
33}
34
35impl Object for ProfileSequence {
36 fn display(&self, _cx: &mut Cx) -> Result<String> {
37 Ok(format!("#<profile-sequence {}>", self.profile))
38 }
39
40 fn as_any(&self) -> &dyn std::any::Any {
41 self
42 }
43}
44
45impl ObjectCompat for ProfileSequence {
46 fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
47 cx.factory().class_stub(
48 CORE_SEQUENCE_CLASS_ID,
49 Symbol::qualified("core", "Sequence"),
50 )
51 }
52
53 fn as_sequence(&self) -> Option<&dyn Sequence> {
54 Some(self)
55 }
56}
57
58impl Sequence for ProfileSequence {
59 fn next_item(&self, cx: &mut Cx) -> Result<Option<SequenceItem>> {
60 seq_next_value(cx, &self.inner)
61 }
62
63 fn close(&self, cx: &mut Cx) -> Result<()> {
64 seq_close_value(cx, &self.inner)
65 }
66
67 fn peek_item(&self, cx: &mut Cx) -> Result<Option<SequenceItem>> {
68 match self.inner.object().as_sequence() {
69 Some(sequence) => seq_peek(cx, sequence),
70 None => Ok(None),
71 }
72 }
73
74 fn is_done(&self, cx: &mut Cx) -> Result<bool> {
75 match self.inner.object().as_sequence() {
76 Some(sequence) => seq_is_done(cx, sequence),
77 None => Ok(false),
78 }
79 }
80}
81
82pub fn sequence_for_profile(cx: &mut Cx, profile: Symbol, sequence: Value) -> Result<Value> {
84 cx.factory()
85 .opaque(Arc::new(ProfileSequence::new(profile, sequence)))
86}