1#[cfg(test)]
4mod tests;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum STATUSTYPE {
9 PLAYING,
11 PAUSED,
13 STOPPED,
15 EXITING,
17 UNDEFINED,
19}
20
21#[derive(Debug, Clone, PartialEq)]
23pub struct Status {
24 pub status: STATUSTYPE,
26 pub file: Option<String>,
28 pub artist: Option<String>,
30 pub albumartist: Option<String>,
32 pub album: Option<String>,
34 pub discnumber: Option<u32>,
36 pub tracknumber: Option<u32>,
38 pub title: Option<String>,
40 pub date: Option<u32>,
42 pub duration: Option<u32>,
44}
45
46impl Status {
47 pub fn new() -> Status {
49 return Status { status: STATUSTYPE::UNDEFINED, file: None, artist: None, albumartist: None, album: None, discnumber: None, tracknumber: None, title: None, date: None, duration: None };
50 }
51}
52
53pub fn serialise(status: &str) -> Status {
56 let mut modstatus = status.to_string();
57 modstatus = modstatus.replace("status ", ";;st:");
58 modstatus = modstatus.replace("file ", ";;fi:");
59 modstatus = modstatus.replace("albumartist ", ";;ab:");
60 modstatus = modstatus.replace("artist ", ";;ar:");
61 modstatus = modstatus.replace("album ", ";;al:");
62 modstatus = modstatus.replace("discnumber ", ";;dn:");
63 modstatus = modstatus.replace("tracknumber ", ";;tn:");
64 modstatus = modstatus.replace("title ", ";;ti:");
65 modstatus = modstatus.replace("date ", ";;da:");
66 modstatus = modstatus.replace("duration ", ";;du:");
67
68 let segments: Vec<String> = modstatus.split_whitespace().map(|x| x.to_string()).collect();
69
70
71 let mut status = Status::new();
72 let mut multi_line_file_name = false;
73 let mut segtype_multi = "".to_string();
74 let mut multi_line_scratch = "".to_string();
75 let mut i = 0;
76 loop {
77 let x;
78 if i >= segments.len() {
79 x = "".to_string();
80 } else {
81 x = segments[i].clone();
82 }
83
84 if !multi_line_file_name && x.starts_with(";;") {
85 let (first, last) = x.split_at(5);
86 let segtype = first.replace(";;", "").replace(":", "");
87
88 if segtype == "st" {
89 match last {
90 "playing" => status.status = STATUSTYPE::PLAYING,
91 "paused" => status.status = STATUSTYPE::PAUSED,
92 "stopped" => status.status = STATUSTYPE::STOPPED,
93 "exiting" => status.status = STATUSTYPE::EXITING,
94 _ => status.status = STATUSTYPE::UNDEFINED,
95 }
96 } else if segtype == "fi" || segtype == "ar" || segtype == "ab" || segtype == "al" || segtype == "ti" {
97 multi_line_scratch = last.to_string();
98 multi_line_file_name = true;
99 segtype_multi = segtype.to_string();
100 } else if segtype == "dn" {
101 let parsed = last.parse::<u32>();
102
103 if parsed.is_ok() {
104 status.discnumber = Some(parsed.unwrap().clone());
105 }
106 } else if segtype == "tn" {
107 let parsed = last.parse::<u32>();
108
109 if parsed.is_ok() {
110 status.tracknumber = Some(parsed.unwrap().clone());
111 }
112 } else if segtype == "da" {
113 let parsed = last.parse::<u32>();
114
115 if parsed.is_ok() {
116 status.date = Some(parsed.unwrap().clone());
117 }
118 } else if segtype == "du" {
119 let parsed = last.parse::<u32>();
120
121 if parsed.is_ok() {
122 status.duration = Some(parsed.unwrap().clone());
123 }
124 }
125 i = i + 1;
126 if i >= segments.len() {
127 break;
128 }
129 } else if multi_line_file_name {
130 if !x.starts_with(";;") && x != "".to_string() {
131 multi_line_scratch = format!("{} {}", multi_line_scratch, x.to_string());
132 i = i + 1;
133 } else {
134 multi_line_file_name = false;
135 match segtype_multi.as_str() {
136 "fi" => status.file = Some(multi_line_scratch.clone()),
137 "ar" => status.artist = Some(multi_line_scratch.clone()),
138 "ab" => status.albumartist = Some(multi_line_scratch.clone()),
139 "al" => status.album = Some(multi_line_scratch.clone()),
140 "ti" => status.title = Some(multi_line_scratch.clone()),
141 _ => panic!(),
142 }
143 }
144 } else {
145 i = i + 1;
146 }
147 }
148
149 return status;
150}
151