makepad_shader_compiler/
swizzle.rs

1use {
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}