datastar/
execute_script.rs1use {
6 crate::{
7 DatastarEvent,
8 consts::{self, ElementPatchMode},
9 },
10 core::time::Duration,
11};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct ExecuteScript {
16 pub id: Option<String>,
20 pub retry: Duration,
23 pub script: String,
25 pub auto_remove: Option<bool>,
27 pub attributes: Vec<String>,
30}
31
32impl ExecuteScript {
33 pub fn new(script: impl Into<String>) -> Self {
35 Self {
36 id: None,
37 retry: Duration::from_millis(consts::DEFAULT_SSE_RETRY_DURATION),
38 script: script.into(),
39 auto_remove: Default::default(),
40 attributes: Default::default(),
41 }
42 }
43
44 pub fn id(mut self, id: impl Into<String>) -> Self {
46 self.id = Some(id.into());
47 self
48 }
49
50 pub fn retry(mut self, retry: Duration) -> Self {
52 self.retry = retry;
53 self
54 }
55
56 pub fn auto_remove(mut self, auto_remove: bool) -> Self {
58 self.auto_remove = Some(auto_remove);
59 self
60 }
61
62 pub fn attributes(mut self, attributes: impl IntoIterator<Item = impl Into<String>>) -> Self {
64 self.attributes = attributes.into_iter().map(Into::into).collect();
65 self
66 }
67
68 #[inline]
70 pub fn into_datastar_event(mut self) -> DatastarEvent {
71 let id = self.id.take();
72 self.convert_to_datastar_event_inner(id)
73 }
74
75 #[inline]
77 pub fn as_datastar_event(&self) -> DatastarEvent {
78 self.convert_to_datastar_event_inner(self.id.clone())
79 }
80
81 fn convert_to_datastar_event_inner(&self, id: Option<String>) -> DatastarEvent {
82 let mut data: Vec<String> = Vec::new();
83
84 data.push(format!("{} body", consts::SELECTOR_DATALINE_LITERAL));
85
86 data.push(format!(
87 "{} {}",
88 consts::MODE_DATALINE_LITERAL,
89 ElementPatchMode::Append.as_str(),
90 ));
91
92 let mut s = format!("{} <script", consts::ELEMENTS_DATALINE_LITERAL);
93
94 if self.auto_remove.unwrap_or(true) {
95 s.push_str(r##" data-effect="el.remove()""##);
96 }
97
98 for attribute in &self.attributes {
99 s.push(' ');
100 s.push_str(attribute.as_str());
101 }
102
103 let mut scripts_lines = self.script.lines();
104
105 s.push('>');
106 s.push_str(scripts_lines.next().unwrap_or_default());
107 data.push(s);
108
109 for line in scripts_lines {
110 data.push(format!("{} {}", consts::ELEMENTS_DATALINE_LITERAL, line));
111 }
112
113 data.last_mut().unwrap().push_str("</script>");
114
115 DatastarEvent {
116 event: consts::EventType::PatchElements,
117 id,
118 retry: self.retry,
119 data,
120 }
121 }
122}
123
124impl From<&ExecuteScript> for DatastarEvent {
125 #[inline]
126 fn from(val: &ExecuteScript) -> Self {
127 val.as_datastar_event()
128 }
129}
130
131impl From<ExecuteScript> for DatastarEvent {
132 #[inline]
133 fn from(val: ExecuteScript) -> Self {
134 val.into_datastar_event()
135 }
136}