rune/runtime/
label.rs
1use core::cell::Cell;
4use core::fmt;
5use core::num::NonZeroUsize;
6
7use crate as rune;
8use crate::alloc::borrow::Cow;
9use crate::alloc::prelude::*;
10use ::rust_alloc::rc::Rc;
11
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, TryClone)]
16pub(crate) struct Label {
17 pub(crate) name: &'static str,
18 pub(crate) index: usize,
19 #[try_clone(with = Rc::clone)]
20 jump: Rc<Cell<Option<NonZeroUsize>>>,
21}
22
23impl Label {
24 pub(crate) fn new(name: &'static str, index: usize) -> Self {
26 Self {
27 name,
28 index,
29 jump: Rc::new(Cell::new(None)),
30 }
31 }
32
33 pub(crate) fn jump(&self) -> Option<usize> {
35 Some(self.jump.get()?.get().wrapping_sub(1))
36 }
37
38 pub(crate) fn set_jump(&self, jump: usize) -> bool {
40 let Some(jump) = NonZeroUsize::new(jump.wrapping_add(1)) else {
41 return false;
42 };
43
44 self.jump.replace(Some(jump));
45 true
46 }
47
48 pub(crate) fn to_debug_label(&self) -> DebugLabel {
50 DebugLabel {
51 name: self.name.into(),
52 index: self.index,
53 jump: self.jump.get(),
54 }
55 }
56}
57
58impl fmt::Display for Label {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 if let Some(jump) = self.jump() {
61 write!(f, "{}_{} ({jump})", self.name, self.index)
62 } else {
63 write!(f, "{}_{}", self.name, self.index)
64 }
65 }
66}
67
68#[derive(Debug, TryClone, PartialEq, Eq, Hash, Serialize, Deserialize)]
70pub struct DebugLabel {
71 name: Cow<'static, str>,
73 index: usize,
75 jump: Option<NonZeroUsize>,
77}
78
79impl DebugLabel {
80 pub(crate) fn jump(&self) -> Option<usize> {
82 Some(self.jump?.get().wrapping_sub(1))
83 }
84}
85
86impl fmt::Display for DebugLabel {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 write!(f, "{}_{}", self.name, self.index)?;
89
90 if let Some(jump) = self.jump() {
91 write!(f, " ({jump})")?;
92 }
93
94 Ok(())
95 }
96}