@@ -3,40 +3,42 @@ use super::ApeTagRef;
33use crate :: ape:: constants:: APE_PREAMBLE ;
44use crate :: ape:: tag:: read;
55use crate :: config:: WriteOptions ;
6- use crate :: error:: Result ;
6+ use crate :: error:: { LoftyError , Result } ;
77use crate :: id3:: { find_id3v1, find_id3v2, find_lyrics3v2, FindId3v2Config } ;
88use crate :: macros:: { decode_err, err} ;
99use crate :: probe:: Probe ;
1010use crate :: tag:: item:: ItemValueRef ;
11+ use crate :: util:: io:: { FileLike , Truncate } ;
1112
12- use std:: fs:: File ;
13- use std:: io:: { Cursor , Read , Seek , SeekFrom , Write } ;
13+ use std:: io:: { Cursor , Seek , SeekFrom , Write } ;
1414
1515use byteorder:: { LittleEndian , WriteBytesExt } ;
1616
1717#[ allow( clippy:: shadow_unrelated) ]
18- pub ( crate ) fn write_to < ' a , I > (
19- data : & mut File ,
18+ pub ( crate ) fn write_to < ' a , F , I > (
19+ file : & mut F ,
2020 tag_ref : & mut ApeTagRef < ' a , I > ,
2121 write_options : WriteOptions ,
2222) -> Result < ( ) >
2323where
2424 I : Iterator < Item = ApeItemRef < ' a > > ,
25+ F : FileLike ,
26+ LoftyError : From < <F as Truncate >:: Error > ,
2527{
26- let probe = Probe :: new ( data ) . guess_file_type ( ) ?;
28+ let probe = Probe :: new ( file ) . guess_file_type ( ) ?;
2729
2830 match probe. file_type ( ) {
2931 Some ( ft) if super :: ApeTag :: SUPPORTED_FORMATS . contains ( & ft) => { } ,
3032 _ => err ! ( UnsupportedTag ) ,
3133 }
3234
33- let data = probe. into_inner ( ) ;
35+ let file = probe. into_inner ( ) ;
3436
3537 // We don't actually need the ID3v2 tag, but reading it will seek to the end of it if it exists
36- find_id3v2 ( data , FindId3v2Config :: NO_READ_TAG ) ?;
38+ find_id3v2 ( file , FindId3v2Config :: NO_READ_TAG ) ?;
3739
3840 let mut ape_preamble = [ 0 ; 8 ] ;
39- data . read_exact ( & mut ape_preamble) ?;
41+ file . read_exact ( & mut ape_preamble) ?;
4042
4143 // We have to check the APE tag for any read only items first
4244 let mut read_only = None ;
4547 // If one is found, it'll be removed and rewritten at the bottom, where it should be
4648 let mut header_ape_tag = ( false , ( 0 , 0 ) ) ;
4749
48- let start = data . stream_position ( ) ?;
49- match read:: read_ape_tag ( data , false ) ? {
50+ let start = file . stream_position ( ) ?;
51+ match read:: read_ape_tag ( file , false ) ? {
5052 Some ( ( mut existing_tag, header) ) => {
5153 if write_options. respect_read_only {
5254 // Only keep metadata around that's marked read only
@@ -60,25 +62,25 @@ where
6062 header_ape_tag = ( true , ( start, start + u64:: from ( header. size ) ) )
6163 } ,
6264 None => {
63- data . seek ( SeekFrom :: Current ( -8 ) ) ?;
65+ file . seek ( SeekFrom :: Current ( -8 ) ) ?;
6466 } ,
6567 }
6668
6769 // Skip over ID3v1 and Lyrics3v2 tags
68- find_id3v1 ( data , false ) ?;
69- find_lyrics3v2 ( data ) ?;
70+ find_id3v1 ( file , false ) ?;
71+ find_lyrics3v2 ( file ) ?;
7072
7173 // In case there's no ape tag already, this is the spot it belongs
72- let ape_position = data . stream_position ( ) ?;
74+ let ape_position = file . stream_position ( ) ?;
7375
7476 // Now search for an APE tag at the end
75- data . seek ( SeekFrom :: Current ( -32 ) ) ?;
77+ file . seek ( SeekFrom :: Current ( -32 ) ) ?;
7678
7779 let mut ape_tag_location = None ;
7880
7981 // Also check this tag for any read only items
80- let start = data . stream_position ( ) ? as usize + 32 ;
81- if let Some ( ( mut existing_tag, header) ) = read:: read_ape_tag ( data , true ) ? {
82+ let start = file . stream_position ( ) ? as usize + 32 ;
83+ if let Some ( ( mut existing_tag, header) ) = read:: read_ape_tag ( file , true ) ? {
8284 if write_options. respect_read_only {
8385 existing_tag. items . retain ( |i| i. read_only ) ;
8486
@@ -114,10 +116,10 @@ where
114116 tag = create_ape_tag ( tag_ref, std:: iter:: empty ( ) , write_options) ?;
115117 } ;
116118
117- data . rewind ( ) ?;
119+ file . rewind ( ) ?;
118120
119121 let mut file_bytes = Vec :: new ( ) ;
120- data . read_to_end ( & mut file_bytes) ?;
122+ file . read_to_end ( & mut file_bytes) ?;
121123
122124 // Write the tag in the appropriate place
123125 if let Some ( range) = ape_tag_location {
@@ -131,9 +133,9 @@ where
131133 file_bytes. drain ( header_ape_tag. 1 . 0 as usize ..header_ape_tag. 1 . 1 as usize ) ;
132134 }
133135
134- data . rewind ( ) ?;
135- data . set_len ( 0 ) ?;
136- data . write_all ( & file_bytes) ?;
136+ file . rewind ( ) ?;
137+ file . truncate ( 0 ) ?;
138+ file . write_all ( & file_bytes) ?;
137139
138140 Ok ( ( ) )
139141}
0 commit comments