rune/runtime/
control_flow.rs1use core::ops;
2
3use crate as rune;
4use crate::alloc;
5use crate::alloc::clone::TryClone;
6use crate::alloc::fmt::TryWrite;
7use crate::Any;
8
9use super::{
10 EnvProtocolCaller, Formatter, FromValue, ProtocolCaller, RuntimeError, ToValue, Value, VmError,
11};
12
13#[derive(Debug, Clone, TryClone, Any)]
29#[try_clone(crate)]
30#[rune(item = ::std::ops)]
31pub enum ControlFlow {
32 #[rune(constructor)]
34 Continue(#[rune(get, set)] Value),
35 #[rune(constructor)]
37 Break(#[rune(get, set)] Value),
38}
39
40impl ControlFlow {
41 #[rune::function(keep, protocol = PARTIAL_EQ)]
62 pub(crate) fn partial_eq(&self, other: &Self) -> Result<bool, VmError> {
63 Self::partial_eq_with(self, other, &mut EnvProtocolCaller)
64 }
65
66 pub(crate) fn partial_eq_with(
67 &self,
68 other: &Self,
69 caller: &mut dyn ProtocolCaller,
70 ) -> Result<bool, VmError> {
71 match (self, other) {
72 (ControlFlow::Continue(a), ControlFlow::Continue(b)) => {
73 Value::partial_eq_with(a, b, caller)
74 }
75 (ControlFlow::Break(a), ControlFlow::Break(b)) => Value::partial_eq_with(a, b, caller),
76 _ => Ok(false),
77 }
78 }
79
80 #[rune::function(keep, protocol = EQ)]
101 pub(crate) fn eq(&self, other: &ControlFlow) -> Result<bool, VmError> {
102 self.eq_with(other, &mut EnvProtocolCaller)
103 }
104
105 pub(crate) fn eq_with(
106 &self,
107 other: &ControlFlow,
108 caller: &mut dyn ProtocolCaller,
109 ) -> Result<bool, VmError> {
110 match (self, other) {
111 (ControlFlow::Continue(a), ControlFlow::Continue(b)) => Value::eq_with(a, b, caller),
112 (ControlFlow::Break(a), ControlFlow::Break(b)) => Value::eq_with(a, b, caller),
113 _ => Ok(false),
114 }
115 }
116
117 #[rune::function(keep, protocol = DEBUG_FMT)]
127 pub(crate) fn debug_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
128 Self::debug_fmt_with(self, f, &mut EnvProtocolCaller)
129 }
130
131 pub(crate) fn debug_fmt_with(
132 &self,
133 f: &mut Formatter,
134 caller: &mut dyn ProtocolCaller,
135 ) -> Result<(), VmError> {
136 match self {
137 ControlFlow::Continue(value) => {
138 write!(f, "Continue(")?;
139 Value::debug_fmt_with(value, f, caller)?;
140 write!(f, ")")?;
141 }
142 ControlFlow::Break(value) => {
143 write!(f, "Break(")?;
144 Value::debug_fmt_with(value, f, caller)?;
145 write!(f, ")")?;
146 }
147 }
148
149 Ok(())
150 }
151
152 #[rune::function(keep, protocol = CLONE)]
165 pub(crate) fn clone(&self) -> alloc::Result<Self> {
166 self.try_clone()
167 }
168}
169
170impl<B, C> ToValue for ops::ControlFlow<B, C>
171where
172 B: ToValue,
173 C: ToValue,
174{
175 #[inline]
176 fn to_value(self) -> Result<Value, RuntimeError> {
177 let value = match self {
178 ops::ControlFlow::Continue(value) => ControlFlow::Continue(C::to_value(value)?),
179 ops::ControlFlow::Break(value) => ControlFlow::Break(B::to_value(value)?),
180 };
181
182 Ok(Value::try_from(value)?)
183 }
184}
185
186impl<B, C> FromValue for ops::ControlFlow<B, C>
187where
188 B: FromValue,
189 C: FromValue,
190{
191 #[inline]
192 fn from_value(value: Value) -> Result<Self, RuntimeError> {
193 Ok(match &*value.borrow_ref::<ControlFlow>()? {
194 ControlFlow::Continue(value) => {
195 ops::ControlFlow::Continue(C::from_value(value.clone())?)
196 }
197 ControlFlow::Break(value) => ops::ControlFlow::Break(B::from_value(value.clone())?),
198 })
199 }
200}