makepad_shader_compiler/
swizzle.rs1use {
2 std::fmt,
3 std::slice,
4 crate::shader_ast::Ident
5};
6
7#[derive(Clone, Debug)]
8pub struct Swizzle {
9 indices: Vec<usize>,
10}
11
12#[allow(clippy::len_without_is_empty)]
13impl Swizzle {
14 pub fn parse(ident: Ident) -> Option<Swizzle> {
15 let mut indices = Vec::new();
16 ident.to_id().as_string(|string| {
17 let mut chars = string.unwrap().chars();
18 let mut ch = chars.next().unwrap();
19 match ch {
20 'x' | 'y' | 'z' | 'w' => loop {
21 indices.push(match ch {
22 'x' => 0,
23 'y' => 1,
24 'z' => 2,
25 'w' => 3,
26 _ => return None,
27 });
28 ch = match chars.next() {
29 Some(ch) => ch,
30 None => break,
31 };
32 },
33 'r' | 'g' | 'b' | 'a' => loop {
34 indices.push(match ch {
35 'r' => 0,
36 'g' => 1,
37 'b' => 2,
38 'a' => 3,
39 _ => return None,
40 });
41 ch = match chars.next() {
42 Some(ch) => ch,
43 None => break,
44 };
45 },
46 _ => return None,
47 }
48 Some(Swizzle { indices })
49 })
50 }
51
52 pub fn from_range(start: usize, end: usize) -> Swizzle {
53 let mut indices = Vec::new();
54 for index in start..end {
55 indices.push(index)
56 }
57 Swizzle { indices }
58 }
59
60 pub fn len(&self) -> usize {
61 self.indices.len()
62 }
63
64 pub fn iter(&self) -> Iter {
65 Iter(self.indices.iter())
66 }
67}
68
69impl fmt::Display for Swizzle {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 for index in &self.indices {
72 write!(
73 f,
74 "{}",
75 match index {
76 0 => "x",
77 1 => "y",
78 2 => "z",
79 3 => "w",
80 _ => panic!(),
81 }
82 )?;
83 }
84 Ok(())
85 }
86}
87impl<'a> IntoIterator for &'a Swizzle {
88 type Item = &'a usize;
89 type IntoIter = Iter<'a>;
90
91 fn into_iter(self) -> Iter<'a> {
92 self.iter()
93 }
94}
95
96pub struct Iter<'a>(slice::Iter<'a, usize>);
97
98impl<'a> Iterator for Iter<'a> {
99 type Item = &'a usize;
100
101 fn next(&mut self) -> Option<&'a usize> {
102 self.0.next()
103 }
104}