1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use flate2::Compression;
use crate::{
cli::CliDirective,
directives::{
GenBatchDirective,
GenSingleDirective,
GenTarDirective,
GenTarGzDirective,
},
storage::StorageBackend,
};
#[derive(Debug, thiserror::Error)]
pub enum CompressionArgError {
#[error(transparent)]
NotInteger(#[from] std::num::ParseIntError),
#[error("Compression level must be between 0 and 9 (found {input})")]
ValueOutOfRange { input: u32 },
}
pub(crate) fn try_compression_from_str(arg: &str) -> Result<Compression, CompressionArgError> {
let compression_level = arg.parse::<u32>()?;
if compression_level > 9 {
return Err(CompressionArgError::ValueOutOfRange { input: compression_level });
}
Ok(Compression::new(compression_level))
}
pub(crate) fn write_melodies_to_backend<B: StorageBackend>(
note_set: libatm::MIDINoteSet,
melody_length: u32,
mut backend: B,
) {
let notes = libatm::MIDINoteVec::from(note_set);
let num_melodies = crate::utils::gen_num_melodies(notes.len() as u32, melody_length);
let mut pb = pbr::ProgressBar::new(num_melodies);
pb.set_max_refresh_rate(Some(std::time::Duration::from_millis(500)));
for melody_ref in crate::utils::gen_sequences(¬es, melody_length) {
let melody = melody_ref.iter().map(|n| *n.clone()).collect::<libatm::MIDINoteVec>();
if let Err(err) = backend.append_melody(melody, None) {
println!("::: WARNING: Failed to add melody to storage backend ({:?})", err);
}
pb.inc();
}
pb.finish_println("");
if let Err(err) = backend.finish() {
println!("::: ERROR: Failed to finish writing to storage backend ({:?})", err);
std::process::exit(1);
}
}
#[derive(structopt::StructOpt)]
pub enum GenDirective {
#[structopt(name="batch")]
GenBatch(GenBatchDirective),
#[structopt(name="single")]
GenSingle(GenSingleDirective),
#[structopt(name="tar")]
GenTar(GenTarDirective),
#[structopt(name="tar-gz")]
GenTarGz(GenTarGzDirective),
}
impl CliDirective for GenDirective {
fn run(self) {
match self {
Self::GenBatch(d) => d.run(),
Self::GenSingle(d) => d.run(),
Self::GenTar(d) => d.run(),
Self::GenTarGz(d) => d.run(),
}
}
}