1 use std::fs;
2 
3 use walkdir::WalkDir;
4 
5 use mp4ameta::{AdvisoryRating, Data, MediaType, STANDARD_GENRES, Tag};
6 
7 const EXTENSIONS: [&str; 4] = [".m4a", ".m4b", ".m4p", ".m4v"];
8 
9 #[test]
sample_files()10 fn sample_files() {
11     for d in WalkDir::new("./files")
12         .follow_links(true)
13         .into_iter()
14         .filter_map(|e| e.ok())
15         .filter(|e| e.metadata().map(|m| m.is_file()).unwrap_or(false))
16     {
17         let filename = d.file_name().to_str().unwrap();
18         let mut mp4file = false;
19         for e in EXTENSIONS.iter() {
20             if filename.ends_with(e) {
21                 mp4file = true;
22             }
23         }
24 
25         if !mp4file {
26             continue;
27         }
28 
29         let filepath = d.into_path();
30 
31         println!("{}:", filepath.display());
32         let tag_sample = Tag::read_from_path(&filepath).unwrap();
33         println!("{:#?}", tag_sample);
34     }
35 }
36 
37 #[test]
verify_sample_data()38 fn verify_sample_data() {
39     let tag = Tag::read_from_path("./files/sample.m4a").unwrap();
40 
41     assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Explicit(4)));
42     assert_eq!(tag.album(), Some("TEST ALBUM"));
43     assert_eq!(tag.album_artist(), Some("TEST ALBUM ARTIST"));
44     assert_eq!(tag.artist(), Some("TEST ARTIST"));
45     assert_eq!(tag.bpm(), Some(132));
46     assert_eq!(tag.category(), Some("TEST CATEGORY"));
47     assert_eq!(tag.comment(), Some("TEST COMMENT"));
48     assert_eq!(tag.compilation(), true);
49     assert_eq!(tag.composer(), Some("TEST COMPOSER"));
50     assert_eq!(tag.copyright(), Some("TEST COPYRIGHT"));
51     assert_eq!(tag.description(), Some("TEST DESCRIPTION"));
52     assert_eq!(tag.disc(), (Some(1), Some(2)));
53     assert_eq!(tag.disc_number(), Some(1));
54     assert_eq!(tag.total_discs(), Some(2));
55     assert_eq!(tag.encoder(), Some("Lavf58.29.100"));
56     assert_eq!(tag.gapless_playback(), true);
57     assert_eq!(tag.genre(), Some("Hard Rock"));
58     assert_eq!(tag.grouping(), Some("TEST GROUPING"));
59     assert_eq!(tag.keyword(), Some("TEST KEYWORD"));
60     assert_eq!(tag.lyrics(), Some("TEST LYRICS"));
61     assert_eq!(tag.media_type(), Some(MediaType::Normal));
62     assert_eq!(tag.title(), Some("TEST TITLE"));
63     assert_eq!(tag.track(), (Some(7), Some(13)));
64     assert_eq!(tag.track_number(), Some(7));
65     assert_eq!(tag.total_tracks(), Some(13));
66     assert_eq!(tag.year(), Some("2013"));
67     assert_eq!(tag.artwork(), Some(&Data::Png(fs::read("./files/artwork.png").unwrap())));
68     assert_eq!(tag.duration(), Some(0.48523809523809525));
69     assert_eq!(tag.filetype(), Some("M4A \u{0}\u{0}\u{2}\u{0}isomiso2"));
70 }
71 
72 #[test]
write_read()73 fn write_read() {
74     let mut tag = Tag::default();
75     tag.set_advisory_rating(AdvisoryRating::Inoffensive);
76     tag.set_album("NEW ALBUM");
77     tag.set_album_artist("NEW ALBUM ARTIST");
78     tag.set_artist("NEW ARTIST");
79     tag.set_bpm(98);
80     tag.set_category("NEW CATEGORY");
81     tag.set_comment("NEW COMMENT");
82     tag.set_compilation();
83     tag.set_composer("NEW COMPOSER");
84     tag.set_copyright("NEW COPYRIGHT");
85     tag.set_description("NEW DESCRIPTION");
86     tag.set_disc(2, 0);
87     tag.set_encoder("Lavf58.12.100");
88     tag.set_gapless_playback();
89     tag.set_genre("Hard Rock");
90     tag.set_grouping("NEW GROUPING");
91     tag.set_keyword("NEW KEYWORD");
92     tag.set_lyrics("NEW LYRICS");
93     tag.set_media_type(MediaType::AudioBook);
94     tag.set_title("NEW TITLE");
95     tag.set_track(3, 7);
96     tag.set_year("1998");
97     tag.set_artwork(Data::Jpeg(b"NEW ARTWORK".to_vec()));
98 
99     std::fs::copy("./files/sample.m4a", "./files/temp.m4a").unwrap();
100     tag.write_to_path("./files/temp.m4a").unwrap();
101 
102     let tag = Tag::read_from_path("./files/temp.m4a").unwrap();
103     assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Inoffensive));
104     assert_eq!(tag.album(), Some("NEW ALBUM"));
105     assert_eq!(tag.album_artist(), Some("NEW ALBUM ARTIST"));
106     assert_eq!(tag.artist(), Some("NEW ARTIST"));
107     assert_eq!(tag.bpm(), Some(98));
108     assert_eq!(tag.category(), Some("NEW CATEGORY"));
109     assert_eq!(tag.comment(), Some("NEW COMMENT"));
110     assert_eq!(tag.compilation(), true);
111     assert_eq!(tag.composer(), Some("NEW COMPOSER"));
112     assert_eq!(tag.copyright(), Some("NEW COPYRIGHT"));
113     assert_eq!(tag.description(), Some("NEW DESCRIPTION"));
114     assert_eq!(tag.disc(), (Some(2), None));
115     assert_eq!(tag.disc_number(), Some(2));
116     assert_eq!(tag.total_discs(), None);
117     assert_eq!(tag.encoder(), Some("Lavf58.12.100"));
118     assert_eq!(tag.gapless_playback(), true);
119     assert_eq!(tag.genre(), Some("Hard Rock"));
120     assert_eq!(tag.grouping(), Some("NEW GROUPING"));
121     assert_eq!(tag.keyword(), Some("NEW KEYWORD"));
122     assert_eq!(tag.lyrics(), Some("NEW LYRICS"));
123     assert_eq!(tag.media_type(), Some(MediaType::AudioBook));
124     assert_eq!(tag.title(), Some("NEW TITLE"));
125     assert_eq!(tag.track(), (Some(3), Some(7)));
126     assert_eq!(tag.track_number(), Some(3));
127     assert_eq!(tag.total_tracks(), Some(7));
128     assert_eq!(tag.year(), Some("1998"));
129     assert_eq!(tag.artwork(), Some(&Data::Jpeg(b"NEW ARTWORK".to_vec())));
130     assert_eq!(tag.duration(), Some(0.48523809523809525));
131     assert_eq!(tag.filetype(), Some("M4A \u{0}\u{0}\u{2}\u{0}isomiso2"));
132 
133     std::fs::remove_file("./files/temp.m4a").unwrap();
134 }
135 
136 #[test]
dump_read()137 fn dump_read() {
138     let mut tag = Tag::default();
139     tag.set_advisory_rating(AdvisoryRating::Explicit(4));
140     tag.set_album("TEST ALBUM");
141     tag.set_album_artist("TEST ALBUM ARTIST");
142     tag.set_artist("TEST ARTIST");
143     tag.set_bpm(132);
144     tag.set_category("TEST CATEGORY");
145     tag.set_comment("TEST COMMENT");
146     tag.set_compilation();
147     tag.set_composer("TEST COMPOSER");
148     tag.set_copyright("TEST COPYRIGHT");
149     tag.set_description("TEST DESCRIPTION");
150     tag.set_disc(1, 2);
151     tag.set_encoder("Lavf58.29.100");
152     tag.set_gapless_playback();
153     tag.set_genre("Hard Rock");
154     tag.set_grouping("TEST GROUPING");
155     tag.set_keyword("TEST KEYWORD");
156     tag.set_lyrics("TEST LYRICS");
157     tag.set_media_type(MediaType::Normal);
158     tag.set_title("TEST TITLE");
159     tag.set_track(7, 13);
160     tag.set_year("2013");
161     tag.set_artwork(Data::Png(b"TEST ARTWORK".to_vec()));
162 
163     tag.dump_to_path("./files/temp.m4a").unwrap();
164 
165     let tag = Tag::read_from_path("./files/temp.m4a").unwrap();
166     assert_eq!(tag.advisory_rating(), Some(AdvisoryRating::Explicit(4)));
167     assert_eq!(tag.album(), Some("TEST ALBUM"));
168     assert_eq!(tag.album_artist(), Some("TEST ALBUM ARTIST"));
169     assert_eq!(tag.artist(), Some("TEST ARTIST"));
170     assert_eq!(tag.bpm(), Some(132));
171     assert_eq!(tag.category(), Some("TEST CATEGORY"));
172     assert_eq!(tag.comment(), Some("TEST COMMENT"));
173     assert_eq!(tag.compilation(), true);
174     assert_eq!(tag.composer(), Some("TEST COMPOSER"));
175     assert_eq!(tag.copyright(), Some("TEST COPYRIGHT"));
176     assert_eq!(tag.description(), Some("TEST DESCRIPTION"));
177     assert_eq!(tag.disc(), (Some(1), Some(2)));
178     assert_eq!(tag.disc_number(), Some(1));
179     assert_eq!(tag.total_discs(), Some(2));
180     assert_eq!(tag.encoder(), Some("Lavf58.29.100"));
181     assert_eq!(tag.gapless_playback(), true);
182     assert_eq!(tag.genre(), Some("Hard Rock"));
183     assert_eq!(tag.grouping(), Some("TEST GROUPING"));
184     assert_eq!(tag.keyword(), Some("TEST KEYWORD"));
185     assert_eq!(tag.lyrics(), Some("TEST LYRICS"));
186     assert_eq!(tag.media_type(), Some(MediaType::Normal));
187     assert_eq!(tag.title(), Some("TEST TITLE"));
188     assert_eq!(tag.track(), (Some(7), Some(13)));
189     assert_eq!(tag.track_number(), Some(7));
190     assert_eq!(tag.total_tracks(), Some(13));
191     assert_eq!(tag.year(), Some("2013"));
192     assert_eq!(tag.artwork(), Some(&Data::Png(b"TEST ARTWORK".to_vec())));
193 
194     std::fs::remove_file("./files/temp.m4a").unwrap();
195 }
196 
197 #[test]
multiple_values()198 fn multiple_values() {
199     let mut tag = Tag::default();
200 
201     tag.add_artist("1");
202     tag.add_artist("2");
203     tag.add_artist("3");
204     tag.add_artist("4");
205 
206     assert_eq!(tag.artist(), Some("1"));
207     {
208         let mut artists = tag.artists();
209         assert_eq!(artists.next(), Some("1"));
210         assert_eq!(artists.next(), Some("2"));
211         assert_eq!(artists.next(), Some("3"));
212         assert_eq!(artists.next(), Some("4"));
213         assert_eq!(artists.next(), None);
214     }
215 
216     tag.set_artist("5");
217 
218     assert_eq!(tag.artist(), Some("5"));
219     {
220         let mut artists = tag.artists();
221         assert_eq!(artists.next(), Some("5"));
222         assert_eq!(artists.next(), None);
223     }
224 
225     tag.add_artist("6");
226     tag.add_artist("7");
227 
228     assert_eq!(tag.artist(), Some("5"));
229     {
230         let mut artists = tag.artists();
231         assert_eq!(artists.next(), Some("5"));
232         assert_eq!(artists.next(), Some("6"));
233         assert_eq!(artists.next(), Some("7"));
234         assert_eq!(artists.next(), None);
235     }
236 
237     tag.remove_artists();
238 
239     assert_eq!(tag.artists().next(), None);
240     assert_eq!(tag.artist(), None);
241 }
242 
243 #[test]
genre_handling()244 fn genre_handling() {
245     let (code, name) = STANDARD_GENRES[4];
246 
247     let mut tag = Tag::default();
248     assert_eq!(tag.genre(), None);
249     assert_eq!(tag.standard_genre(), None);
250     assert_eq!(tag.custom_genre(), None);
251 
252     tag.set_genre(name);
253     assert_eq!(tag.genre(), Some(name));
254     assert_eq!(tag.standard_genre(), Some(code));
255     assert_eq!(tag.custom_genre(), None);
256 
257     tag.set_genre("CUSTOM GENRE");
258     assert_eq!(tag.genre(), Some("CUSTOM GENRE"));
259     assert_eq!(tag.standard_genre(), None);
260     assert_eq!(tag.custom_genre(), Some("CUSTOM GENRE"));
261 
262     tag.remove_genres();
263     assert_eq!(tag.genre(), None);
264     assert_eq!(tag.genres().next(), None);
265 
266     let (code1, name1) = STANDARD_GENRES[6];
267     let (code2, name2) = STANDARD_GENRES[23];
268     tag.add_custom_genre("GENRE 1");
269     tag.add_standard_genre(code1);
270     tag.add_custom_genre("GENRE 2");
271     tag.add_standard_genre(code2);
272 
273     {
274         let mut genres = tag.genres();
275         assert_eq!(genres.next(), Some(name1));
276         assert_eq!(genres.next(), Some(name2));
277         assert_eq!(genres.next(), Some("GENRE 1"));
278         assert_eq!(genres.next(), Some("GENRE 2"));
279         assert_eq!(genres.next(), None);
280 
281         let mut standard_genres = tag.standard_genres();
282         assert_eq!(standard_genres.next(), Some(code1));
283         assert_eq!(standard_genres.next(), Some(code2));
284         assert_eq!(genres.next(), None);
285 
286         let mut custom_genres = tag.custom_genres();
287         assert_eq!(custom_genres.next(), Some("GENRE 1"));
288         assert_eq!(custom_genres.next(), Some("GENRE 2"));
289         assert_eq!(genres.next(), None);
290     }
291 
292     tag.remove_standard_genres();
293     assert_eq!(tag.standard_genres().next(), None);
294     assert_eq!(tag.genres().next(), Some("GENRE 1"));
295 
296     tag.remove_custom_genres();
297     assert_eq!(tag.custom_genres().next(), None);
298     assert_eq!(tag.genres().next(), None);
299 }
300 
301 #[test]
track_disc_handling()302 fn track_disc_handling() {
303     let track_number = 4u16;
304     let total_tracks = 16u16;
305     let disc_number = 2u16;
306     let total_discs = 3u16;
307 
308     let mut tag = Tag::default();
309     assert_eq!(tag.track(), (None, None));
310     assert_eq!(tag.track_number(), None);
311     assert_eq!(tag.total_tracks(), None);
312     assert_eq!(tag.disc(), (None, None));
313     assert_eq!(tag.disc_number(), None);
314     assert_eq!(tag.total_discs(), None);
315 
316     tag.set_track_number(track_number);
317     tag.set_total_tracks(total_tracks);
318     tag.set_disc_number(disc_number);
319     tag.set_total_discs(total_discs);
320 
321     assert_eq!(tag.track(), (Some(track_number), Some(total_tracks)));
322     assert_eq!(tag.track_number(), Some(track_number));
323     assert_eq!(tag.total_tracks(), Some(total_tracks));
324     assert_eq!(tag.disc(), (Some(disc_number), Some(total_discs)));
325     assert_eq!(tag.disc_number(), Some(disc_number));
326     assert_eq!(tag.total_discs(), Some(total_discs));
327 
328     tag.remove_track_number();
329     tag.remove_disc_number();
330 
331     assert_eq!(tag.track(), (None, Some(total_tracks)));
332     assert_eq!(tag.track_number(), None);
333     assert_eq!(tag.total_tracks(), Some(total_tracks));
334     assert_eq!(tag.disc(), (None, Some(total_discs)));
335     assert_eq!(tag.disc_number(), None);
336     assert_eq!(tag.total_discs(), Some(total_discs));
337 
338     tag.remove_total_tracks();
339     tag.remove_total_discs();
340 
341     assert_eq!(tag.track(), (None, None));
342     assert_eq!(tag.track_number(), None);
343     assert_eq!(tag.total_tracks(), None);
344     assert_eq!(tag.disc(), (None, None));
345     assert_eq!(tag.disc_number(), None);
346     assert_eq!(tag.total_discs(), None);
347 }
348 
349 #[test]
work_movement_handling()350 fn work_movement_handling() {
351     let movement = "TEST MOVEMENT";
352     let index = 1u16;
353     let count = 8u16;
354     let work = "TEST WORK";
355 
356     let mut tag = Tag::default();
357     assert_eq!(tag.movement(), None);
358     assert_eq!(tag.movement_count(), None);
359     assert_eq!(tag.movement_index(), None);
360     assert_eq!(tag.show_movement(), false);
361     assert_eq!(tag.work(), None);
362 
363     tag.set_movement(movement);
364     tag.set_movement_count(count);
365     tag.set_movement_index(index);
366     tag.set_show_movement();
367     tag.set_work(work);
368 
369     assert_eq!(tag.movement(), Some(movement));
370     assert_eq!(tag.movement_count(), Some(count));
371     assert_eq!(tag.movement_index(), Some(index));
372     assert_eq!(tag.show_movement(), true);
373     assert_eq!(tag.work(), Some(work));
374 }
375