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
121
use crate::structs::*;
error_chain! {
errors {
#[doc="the path encoding is invalid"]
InvalidPathEncoding(tag: &'static str) {
description("invalid path encoding")
display("invalid path encoding on tag: {}", tag)
}
}
}
pub fn generate_song_txt(header: &Header, lines: &[Line]) -> Result<String> {
let mp3_str = match header.audio_path.to_str() {
Some(x) => x,
None => bail!(ErrorKind::InvalidPathEncoding("MP3")),
};
let mut song_txt_str = format!(
"#TITLE:{}\n#ARTIST:{}\n#MP3:{}\n#BPM:{}\n",
header.title, header.artist, mp3_str, header.bpm
);
if let Some(gap) = header.gap {
song_txt_str.push_str(&format!("#GAP:{}\n", gap));
}
if let Some(cover_path) = header.cover_path.clone() {
let cover_str = match cover_path.to_str() {
Some(x) => x,
None => bail!(ErrorKind::InvalidPathEncoding("COVER")),
};
song_txt_str.push_str(&format!("#COVER:{}\n", cover_str));
}
if let Some(background_path) = header.background_path.clone() {
let background_str = match background_path.to_str() {
Some(x) => x,
None => bail!(ErrorKind::InvalidPathEncoding("BACKGROUND")),
};
song_txt_str.push_str(&format!("#BACKGROUND:{}\n", background_str));
}
if let Some(video_path) = header.video_path.clone() {
let video_str = match video_path.to_str() {
Some(x) => x,
None => bail!(ErrorKind::InvalidPathEncoding("VIDEO")),
};
song_txt_str.push_str(&format!("#VIDEO:{}\n", video_str));
}
if let Some(videogap) = header.video_gap {
song_txt_str.push_str(&format!("#VIDEOGAP:{}\n", videogap));
}
if let Some(genre) = header.genre.clone() {
song_txt_str.push_str(&format!("#GENRE:{}\n", genre));
}
if let Some(edition) = header.edition.clone() {
song_txt_str.push_str(&format!("#EDITION:{}\n", edition));
}
if let Some(language) = header.language.clone() {
song_txt_str.push_str(&format!("#LANGUAGE:{}\n", language));
}
if let Some(year) = header.year {
song_txt_str.push_str(&format!("#YEAR:{}\n", year));
}
if let Some(relative) = header.relative {
if relative {
song_txt_str.push_str("#RELATIVE:YES\n");
} else {
song_txt_str.push_str("#RELATIVE:NO\n");
}
}
if let Some(unknown) = header.unknown.clone() {
for (key, value) in unknown.iter() {
song_txt_str.push_str(&format!("#{}:{}\n", key, value));
}
}
for line in lines.iter() {
if line.start != 0 {
if line.rel.is_some() {
song_txt_str.push_str(format!("- {} {}\n", line.start, line.rel.unwrap()).as_ref());
} else {
song_txt_str.push_str(format!("- {}\n", line.start).as_ref());
}
}
for note in line.notes.iter() {
match *note {
Note::Regular {
start,
duration,
pitch,
ref text,
} => song_txt_str
.push_str(format!(": {} {} {} {}\n", start, duration, pitch, text).as_ref()),
Note::Golden {
start,
duration,
pitch,
ref text,
} => song_txt_str
.push_str(format!("* {} {} {} {}\n", start, duration, pitch, text).as_ref()),
Note::Freestyle {
start,
duration,
pitch,
ref text,
} => song_txt_str
.push_str(format!("F {} {} {} {}\n", start, duration, pitch, text).as_ref()),
Note::PlayerChange { player } => {
song_txt_str.push_str(format!("P{}\n", player).as_ref())
}
};
}
}
song_txt_str.push_str("E");
Ok(song_txt_str)
}