fn main() { let arg_vec_string: Vec = std::env::args().skip(1).collect(); let arg_vec_str: Vec<&str> = arg_vec_string.iter().map(|s| s.as_ref()).collect(); let arg_slice_str: &[&str] = arg_vec_str.as_ref(); match arg_slice_str { [components] => { let characters: Vec = components.chars().collect(); println!("// swizzle characters: {:?}", characters); match characters.len() { 2 => swizzle_2channel(characters), 3 => swizzle_3channel(characters), 4 => swizzle_4channel(characters), z => { println!("illegal component count! expected 2/3/4, got: {}", z); std::process::exit(1); } } } _ => { println!("USAGE: `cargo run --example swizzle_builder -- [components]`"); std::process::exit(1); } } } pub fn swizzle_2channel(mut characters: Vec) { assert_eq!(characters.len(), 2); characters.push('_'); let mut name_set = std::collections::HashSet::new(); for c1 in characters.iter().copied() { for c2 in characters.iter().copied() { let name = format!("{}{}", c1, c2); let no_underscores = name.replace("_", ""); if no_underscores.chars().count() > 1 { name_set.insert(no_underscores); } } } let mut name_list: Vec = name_set.into_iter().collect(); name_list.sort(); println!("use super::*;"); println!("impl Vec2 {{"); for name in name_list.iter() { println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Self {{", name); println!( " Self {{ x: self.{}, y: self.{} }}", name.chars().nth(0).unwrap(), name.chars().nth(1).unwrap() ); println!(" }}"); } println!("}}"); // eprintln!("#![allow(bad_style)]"); eprintln!("#![allow(clippy::float_cmp)]"); eprintln!("use hektor::*;"); for name in name_list.iter() { eprintln!("#[test]"); eprintln!("fn Vec2_{}() {{", name); eprintln!(" let v = Vec2::new(1.0, 2.0);"); eprintln!(" let v_swizzled = v.{}();", name); eprintln!( " assert_eq!(v_swizzled.x(), v.{}());", name.chars().nth(0).unwrap() ); eprintln!( " assert_eq!(v_swizzled.y(), v.{}());", name.chars().nth(1).unwrap() ); eprintln!("}}"); } } pub fn swizzle_3channel(mut characters: Vec) { assert_eq!(characters.len(), 3); characters.push('_'); let mut name_set = std::collections::HashSet::new(); for c1 in characters.iter().copied() { for c2 in characters.iter().copied() { for c3 in characters.iter().copied() { let name = format!("{}{}{}", c1, c2, c3); let no_underscores = name.replace("_", ""); if no_underscores.chars().count() > 1 { name_set.insert(no_underscores); } } } } let mut name_list: Vec = name_set.into_iter().collect(); name_list.sort(); println!("use super::*;"); println!("impl Vec3 {{"); for name in name_list.iter() { match name.chars().count() { 2 => { println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Vec2 {{", name); println!(" self.raw.{}()", name); println!(" }}"); } 3 => { println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Self {{", name); println!(" self.raw.{}()", name); println!(" }}"); } z => panic!("illegal swizzle character count: {}", z), } } println!("}}"); // eprintln!("#![allow(bad_style)]"); eprintln!("#![allow(clippy::float_cmp)]"); eprintln!("use hektor::*;"); for name in name_list.iter() { eprintln!("#[test]"); eprintln!("fn Vec3_{}() {{", name); eprintln!(" let v = Vec3::new(1.0, 2.0, 3.0);"); eprintln!(" let v_swizzled: Vec{} = v.{}();", name.len(), name); eprintln!( " assert_eq!(v_swizzled.x(), v.{}());", name.chars().nth(0).unwrap() ); eprintln!( " assert_eq!(v_swizzled.y(), v.{}());", name.chars().nth(1).unwrap() ); if name.len() > 2 { eprintln!( " assert_eq!(v_swizzled.z(), v.{}());", name.chars().nth(2).unwrap() ); } eprintln!("}}"); } } pub fn swizzle_4channel(mut characters: Vec) { assert_eq!(characters.len(), 4); characters.push('_'); let mut name_set = std::collections::HashSet::new(); for c1 in characters.iter().copied() { for c2 in characters.iter().copied() { for c3 in characters.iter().copied() { for c4 in characters.iter().copied() { let name = format!("{}{}{}{}", c1, c2, c3, c4); let no_underscores = name.replace("_", ""); if no_underscores.chars().count() > 1 { name_set.insert(no_underscores); } } } } } let mut name_list: Vec = name_set.into_iter().collect(); name_list.sort(); println!("use super::*;"); println!("impl Vec4 {{"); for name in name_list.iter() { match name.chars().count() { 2 => { println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Vec2 {{", name); println!(" let temp = self.{}{}();", name, name); println!(" Vec2::new(temp.x(), temp.y())"); println!(" }}"); } 3 => { println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Vec3 {{", name); println!(" Vec3 {{ raw: self.{}{}() }}", name, characters[0]); println!(" }}"); } 4 => { let indexes: [usize; 4] = [ characters .iter() .position(|&ch| ch == name.chars().nth(0).unwrap()) .unwrap(), characters .iter() .position(|&ch| ch == name.chars().nth(1).unwrap()) .unwrap(), characters .iter() .position(|&ch| ch == name.chars().nth(2).unwrap()) .unwrap(), characters .iter() .position(|&ch| ch == name.chars().nth(3).unwrap()) .unwrap(), ]; println!(" /// Swizzle: obtains the `{}` combination", name); println!(" #[inline]"); println!(" pub fn {}(self) -> Self {{", name); println!(" if_sse!{{{{"); println!(" Self {{ raw:"); println!(" shuffle128!(self.raw, self.raw, {:?})", indexes); println!(" }}"); println!(" }} else {{"); println!(" Self {{ raw: ["); for index in indexes.iter().copied() { println!(" self.raw[{}],", index); } println!(" ]}}"); println!(" }}}}"); println!(" }}"); } z => panic!("illegal swizzle character count: {}", z), } } println!("}}"); // eprintln!("#![allow(bad_style)]"); eprintln!("#![allow(clippy::float_cmp)]"); eprintln!("use hektor::*;"); for name in name_list.iter() { eprintln!("#[test]"); eprintln!("fn Vec4_{}() {{", name); eprintln!(" let v = Vec4::new(1.0, 2.0, 3.0, 4.0);"); eprintln!(" let v_swizzled: Vec{} = v.{}();", name.len(), name); eprintln!( " assert_eq!(v_swizzled.x(), v.{}());", name.chars().nth(0).unwrap() ); eprintln!( " assert_eq!(v_swizzled.y(), v.{}());", name.chars().nth(1).unwrap() ); if name.len() > 2 { eprintln!( " assert_eq!(v_swizzled.z(), v.{}());", name.chars().nth(2).unwrap() ); if name.len() > 3 { eprintln!( " assert_eq!(v_swizzled.z(), v.{}());", name.chars().nth(2).unwrap() ); } } eprintln!("}}"); } }