topcoat_runtime/
reactive_scope.rs1use serde::Serialize;
2use topcoat_core::context::Cx;
3use topcoat_view::{NodeViewParts, PartsWriter, ViewHandle};
4use uuid::Uuid;
5
6use crate::{Js, SHARD_ROUTE_PREFIX, ShardId};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
9#[serde(transparent)]
10pub struct ReactiveScopeId(Uuid);
11
12impl ReactiveScopeId {
13 #[inline]
14 #[must_use]
15 pub fn new() -> Self {
16 Self(Uuid::new_v4())
17 }
18}
19
20impl Default for ReactiveScopeId {
21 #[inline]
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27pub struct ReactiveScope {
28 id: ReactiveScopeId,
29 shard_id: ShardId,
30 exprs: Vec<Js>,
31 placeholder: ViewHandle,
32}
33
34impl ReactiveScope {
35 #[inline]
36 #[must_use]
37 pub fn new(shard_id: ShardId, exprs: Vec<Js>, placeholder: ViewHandle) -> Self {
38 Self {
39 id: ReactiveScopeId::new(),
40 shard_id,
41 exprs,
42 placeholder,
43 }
44 }
45}
46
47impl NodeViewParts for ReactiveScope {
48 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
49 let shard_id = self.shard_id.as_str();
50
51 parts.push_comment(|comment| {
58 comment
59 .push_promoted_str_unescaped(&"::topcoat::scope::start(")
60 .push_string_unescaped(serde_json::to_string(&self.id).unwrap())
61 .push_promoted_str_unescaped(&", ")
62 .push_string_unescaped(
63 serde_json::to_string(&format!("{SHARD_ROUTE_PREFIX}/{shard_id}")).unwrap(),
64 )
65 .push_promoted_str_unescaped(&", [");
66 let last = self.exprs.len().saturating_sub(1);
67 for (index, expr) in self.exprs.iter().enumerate() {
68 comment.push_promoted_str_unescaped(&"\"");
69 expr.write(comment);
70 comment.push_promoted_str_unescaped(&"\"");
71 if index != last {
72 comment.push_promoted_str_unescaped(&", ");
73 }
74 }
75 comment.push_promoted_str_unescaped(&"])");
76 });
77 self.placeholder.into_view_parts(cx, parts);
78 parts.push_comment(|comment| {
79 comment
80 .push_promoted_str_unescaped(&"::topcoat::scope::end(")
81 .push_string_unescaped(serde_json::to_string(&self.id).unwrap())
82 .push_promoted_str_unescaped(&")");
83 });
84 }
85}