naga/
block.rs

1use crate::{Span, Statement};
2use std::ops::{Deref, DerefMut, RangeBounds};
3
4/// A code block is a vector of statements, with maybe a vector of spans.
5#[derive(Debug, Clone, Default)]
6#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
7#[cfg_attr(feature = "serialize", serde(transparent))]
8#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9pub struct Block {
10    body: Vec<Statement>,
11    #[cfg(feature = "span")]
12    #[cfg_attr(feature = "serialize", serde(skip))]
13    span_info: Vec<Span>,
14}
15
16impl Block {
17    pub const fn new() -> Self {
18        Self {
19            body: Vec::new(),
20            #[cfg(feature = "span")]
21            span_info: Vec::new(),
22        }
23    }
24
25    pub fn from_vec(body: Vec<Statement>) -> Self {
26        #[cfg(feature = "span")]
27        let span_info = std::iter::repeat(Span::default())
28            .take(body.len())
29            .collect();
30        Self {
31            body,
32            #[cfg(feature = "span")]
33            span_info,
34        }
35    }
36
37    pub fn with_capacity(capacity: usize) -> Self {
38        Self {
39            body: Vec::with_capacity(capacity),
40            #[cfg(feature = "span")]
41            span_info: Vec::with_capacity(capacity),
42        }
43    }
44
45    #[allow(unused_variables)]
46    pub fn push(&mut self, end: Statement, span: Span) {
47        self.body.push(end);
48        #[cfg(feature = "span")]
49        self.span_info.push(span);
50    }
51
52    pub fn extend(&mut self, item: Option<(Statement, Span)>) {
53        if let Some((end, span)) = item {
54            self.push(end, span)
55        }
56    }
57
58    pub fn extend_block(&mut self, other: Self) {
59        #[cfg(feature = "span")]
60        self.span_info.extend(other.span_info);
61        self.body.extend(other.body);
62    }
63
64    pub fn append(&mut self, other: &mut Self) {
65        #[cfg(feature = "span")]
66        self.span_info.append(&mut other.span_info);
67        self.body.append(&mut other.body);
68    }
69
70    pub fn cull<R: RangeBounds<usize> + Clone>(&mut self, range: R) {
71        #[cfg(feature = "span")]
72        self.span_info.drain(range.clone());
73        self.body.drain(range);
74    }
75
76    pub fn splice<R: RangeBounds<usize> + Clone>(&mut self, range: R, other: Self) {
77        #[cfg(feature = "span")]
78        self.span_info
79            .splice(range.clone(), other.span_info.into_iter());
80        self.body.splice(range, other.body.into_iter());
81    }
82    pub fn span_iter(&self) -> impl Iterator<Item = (&Statement, &Span)> {
83        #[cfg(feature = "span")]
84        let span_iter = self.span_info.iter();
85        #[cfg(not(feature = "span"))]
86        let span_iter = std::iter::repeat_with(|| &Span::UNDEFINED);
87
88        self.body.iter().zip(span_iter)
89    }
90
91    pub fn span_iter_mut(&mut self) -> impl Iterator<Item = (&mut Statement, Option<&mut Span>)> {
92        #[cfg(feature = "span")]
93        let span_iter = self.span_info.iter_mut().map(Some);
94        #[cfg(not(feature = "span"))]
95        let span_iter = std::iter::repeat_with(|| None);
96
97        self.body.iter_mut().zip(span_iter)
98    }
99
100    pub fn is_empty(&self) -> bool {
101        self.body.is_empty()
102    }
103
104    pub fn len(&self) -> usize {
105        self.body.len()
106    }
107}
108
109impl Deref for Block {
110    type Target = [Statement];
111    fn deref(&self) -> &[Statement] {
112        &self.body
113    }
114}
115
116impl DerefMut for Block {
117    fn deref_mut(&mut self) -> &mut [Statement] {
118        &mut self.body
119    }
120}
121
122impl<'a> IntoIterator for &'a Block {
123    type Item = &'a Statement;
124    type IntoIter = std::slice::Iter<'a, Statement>;
125
126    fn into_iter(self) -> std::slice::Iter<'a, Statement> {
127        self.iter()
128    }
129}
130
131#[cfg(feature = "deserialize")]
132impl<'de> serde::Deserialize<'de> for Block {
133    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
134    where
135        D: serde::Deserializer<'de>,
136    {
137        Ok(Self::from_vec(Vec::deserialize(deserializer)?))
138    }
139}
140
141impl From<Vec<Statement>> for Block {
142    fn from(body: Vec<Statement>) -> Self {
143        Self::from_vec(body)
144    }
145}