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_attr(feature = "serialize", serde(skip))]
12    span_info: Vec<Span>,
13}
14
15impl Block {
16    pub const fn new() -> Self {
17        Self {
18            body: Vec::new(),
19            span_info: Vec::new(),
20        }
21    }
22
23    pub fn from_vec(body: Vec<Statement>) -> Self {
24        let span_info = std::iter::repeat(Span::default())
25            .take(body.len())
26            .collect();
27        Self { body, span_info }
28    }
29
30    pub fn with_capacity(capacity: usize) -> Self {
31        Self {
32            body: Vec::with_capacity(capacity),
33            span_info: Vec::with_capacity(capacity),
34        }
35    }
36
37    #[allow(unused_variables)]
38    pub fn push(&mut self, end: Statement, span: Span) {
39        self.body.push(end);
40        self.span_info.push(span);
41    }
42
43    pub fn extend(&mut self, item: Option<(Statement, Span)>) {
44        if let Some((end, span)) = item {
45            self.push(end, span)
46        }
47    }
48
49    pub fn extend_block(&mut self, other: Self) {
50        self.span_info.extend(other.span_info);
51        self.body.extend(other.body);
52    }
53
54    pub fn append(&mut self, other: &mut Self) {
55        self.span_info.append(&mut other.span_info);
56        self.body.append(&mut other.body);
57    }
58
59    pub fn cull<R: RangeBounds<usize> + Clone>(&mut self, range: R) {
60        self.span_info.drain(range.clone());
61        self.body.drain(range);
62    }
63
64    pub fn splice<R: RangeBounds<usize> + Clone>(&mut self, range: R, other: Self) {
65        self.span_info.splice(range.clone(), other.span_info);
66        self.body.splice(range, other.body);
67    }
68
69    pub fn span_into_iter(self) -> impl Iterator<Item = (Statement, Span)> {
70        let Block { body, span_info } = self;
71        body.into_iter().zip(span_info)
72    }
73
74    pub fn span_iter(&self) -> impl Iterator<Item = (&Statement, &Span)> {
75        let span_iter = self.span_info.iter();
76        self.body.iter().zip(span_iter)
77    }
78
79    pub fn span_iter_mut(&mut self) -> impl Iterator<Item = (&mut Statement, Option<&mut Span>)> {
80        let span_iter = self.span_info.iter_mut().map(Some);
81        self.body.iter_mut().zip(span_iter)
82    }
83
84    pub fn is_empty(&self) -> bool {
85        self.body.is_empty()
86    }
87
88    pub fn len(&self) -> usize {
89        self.body.len()
90    }
91}
92
93impl Deref for Block {
94    type Target = [Statement];
95    fn deref(&self) -> &[Statement] {
96        &self.body
97    }
98}
99
100impl DerefMut for Block {
101    fn deref_mut(&mut self) -> &mut [Statement] {
102        &mut self.body
103    }
104}
105
106impl<'a> IntoIterator for &'a Block {
107    type Item = &'a Statement;
108    type IntoIter = std::slice::Iter<'a, Statement>;
109
110    fn into_iter(self) -> std::slice::Iter<'a, Statement> {
111        self.iter()
112    }
113}
114
115#[cfg(feature = "deserialize")]
116impl<'de> serde::Deserialize<'de> for Block {
117    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118    where
119        D: serde::Deserializer<'de>,
120    {
121        Ok(Self::from_vec(Vec::deserialize(deserializer)?))
122    }
123}
124
125impl From<Vec<Statement>> for Block {
126    fn from(body: Vec<Statement>) -> Self {
127        Self::from_vec(body)
128    }
129}