1pub trait Mosh {
5 fn glitch(&self, value: &mut [u8]);
6}
7
8pub enum MoshChunk {
10 ChannelSwap(usize, usize, usize),
11 Flip,
12}
13
14pub enum MoshLine {
16 ChannelShift(usize, usize, usize),
17 Shift(usize),
18 Reverse,
19}
20
21impl Mosh for MoshChunk {
22 fn glitch(&self, chunk: &mut [u8]) {
23 match self {
24 Self::ChannelSwap(channel_1, channel_2, channel_count) => {
25 let chunk_length = chunk.len();
26 let channel_value_count = chunk_length / channel_count;
27
28 for i in 0..channel_value_count {
29 let channel_1_index = (i * channel_count) + channel_1;
30 let channel_2_index = (i * channel_count) + channel_2;
31
32 chunk.swap(channel_1_index, channel_2_index);
33 }
34 }
35
36 Self::Flip => chunk.reverse(),
37 }
38 }
39}
40
41impl Mosh for MoshLine {
42 fn glitch(&self, line: &mut [u8]) {
43 match self {
44 Self::ChannelShift(amount, channel, channel_count) => {
45 let line_length = line.len();
46 let channel_value_count = line_length / channel_count;
47
48 for i in 0..channel_value_count {
49 let current_index = (i * channel_count + channel) % line_length;
50 let target_index =
51 (i * channel_count + channel + (channel + 1) * amount) % line_length;
52
53 line.swap(current_index, target_index);
54 }
55 }
56
57 Self::Shift(amount) => line.rotate_left(*amount),
58 Self::Reverse => line.reverse(),
59 }
60 }
61}