@@ -4,6 +4,8 @@ mod simple_tag;
4
4
mod tag;
5
5
mod tag_name;
6
6
mod target;
7
+ #[ cfg( test) ]
8
+ mod tests;
7
9
mod write;
8
10
9
11
pub use attached_file:: * ;
@@ -70,26 +72,12 @@ pub struct MatroskaTagKey<'a>(TargetType, Cow<'a, str>);
70
72
71
73
impl MatroskaTag {
72
74
fn get ( & self , key : MatroskaTagKey < ' _ > ) -> Option < & SimpleTag < ' _ > > {
73
- fn tag_matches_target ( tag : & Tag < ' _ > , target_type : TargetType ) -> bool {
74
- let Some ( target) = & tag. target else {
75
- // An empty target is implicitly `Album`
76
- return target_type == TargetType :: Album ;
77
- } ;
78
-
79
- target. is_candidate_for_type ( target_type)
80
- }
81
-
82
75
let MatroskaTagKey ( target, key) = key;
83
76
84
- let applicable_tags = self
85
- . tags
86
- . iter ( )
87
- . filter ( |tag| tag_matches_target ( tag, target) ) ;
77
+ let applicable_tags = self . tags . iter ( ) . filter ( |tag| tag. matches_target ( target) ) ;
88
78
for applicable_tag in applicable_tags {
89
79
for item in applicable_tag. simple_tags . iter ( ) {
90
- if item. name == key
91
- && ( item. language . is_none ( )
92
- || matches ! ( & item. language, Some ( Language :: Iso639_2 ( l) ) if l == "und" ) )
80
+ if item. name == key && matches ! ( & item. language, Language :: Iso639_2 ( l) if l == "und" )
93
81
{
94
82
return Some ( item) ;
95
83
}
@@ -99,6 +87,33 @@ impl MatroskaTag {
99
87
None
100
88
}
101
89
90
+ fn get_or_insert_tag_for_type < ' a > (
91
+ & ' a mut self ,
92
+ target_type : TargetType ,
93
+ ) -> & ' a mut Tag < ' static > {
94
+ let mut pos = None ;
95
+ if let Some ( applicable_tag_pos) = self
96
+ . tags
97
+ . iter ( )
98
+ . position ( |tag| tag. matches_target ( target_type) )
99
+ {
100
+ pos = Some ( applicable_tag_pos) ;
101
+ }
102
+
103
+ if pos. is_none ( ) {
104
+ pos = Some ( self . tags . len ( ) ) ;
105
+
106
+ let mut new_tag = Tag :: default ( ) ;
107
+ if target_type != TargetType :: Album {
108
+ new_tag. target = Some ( Target :: from ( target_type) ) ;
109
+ }
110
+
111
+ self . tags . push ( new_tag) ;
112
+ }
113
+
114
+ self . tags . get_mut ( pos. unwrap ( ) ) . unwrap ( )
115
+ }
116
+
102
117
fn get_str ( & self , key : MatroskaTagKey < ' _ > ) -> Option < Cow < ' _ , str > > {
103
118
let simple_tag = self . get ( key) ?;
104
119
simple_tag. get_str ( ) . map ( Cow :: from)
@@ -229,8 +244,12 @@ impl Accessor for MatroskaTag {
229
244
) ;
230
245
231
246
fn track ( & self ) -> Option < u32 > {
232
- // `PART_NUMBER` at level Track
233
- todo ! ( )
247
+ self . get ( MatroskaTagKey (
248
+ TargetType :: Track ,
249
+ Cow :: Borrowed ( "PART_NUMBER" ) ,
250
+ ) )
251
+ . and_then ( SimpleTag :: get_str)
252
+ . and_then ( |val| val. parse :: < u32 > ( ) . ok ( ) )
234
253
}
235
254
236
255
fn set_track ( & mut self , _value : u32 ) {
@@ -242,8 +261,12 @@ impl Accessor for MatroskaTag {
242
261
}
243
262
244
263
fn track_total ( & self ) -> Option < u32 > {
245
- // `TOTAL_PARTS` at level album
246
- todo ! ( )
264
+ self . get ( MatroskaTagKey (
265
+ TargetType :: Album ,
266
+ Cow :: Borrowed ( "TOTAL_PARTS" ) ,
267
+ ) )
268
+ . and_then ( SimpleTag :: get_str)
269
+ . and_then ( |val| val. parse :: < u32 > ( ) . ok ( ) )
247
270
}
248
271
249
272
fn set_track_total ( & mut self , _value : u32 ) {
@@ -318,19 +341,6 @@ impl TagExt for MatroskaTag {
318
341
todo ! ( )
319
342
}
320
343
321
- fn remove_from_path < P : AsRef < Path > > ( & self , _path : P ) -> std:: result:: Result < ( ) , Self :: Err > {
322
- todo ! ( )
323
- }
324
-
325
- fn remove_from < F > ( & self , _file : & mut F ) -> std:: result:: Result < ( ) , Self :: Err >
326
- where
327
- F : FileLike ,
328
- LoftyError : From < <F as Truncate >:: Error > ,
329
- LoftyError : From < <F as Length >:: Error > ,
330
- {
331
- todo ! ( )
332
- }
333
-
334
344
fn clear ( & mut self ) {
335
345
self . tags . clear ( ) ;
336
346
self . attached_files . clear ( ) ;
0 commit comments