11use crate :: error:: Result ;
22use crate :: macros:: encode_err;
3- use crate :: picture:: MimeType ;
3+ use crate :: picture:: { MimeType , Picture } ;
44
5+ use std:: borrow:: Cow ;
56use std:: fmt:: Debug ;
67
78/// Some attached file
89///
910/// This element contains any attached files, similar to the [GEOB]
1011/// frame in ID3v2. The difference is, this is *also* used for images.
1112///
13+ /// **Unsupported in WebM**
14+ ///
1215/// [GEOB]: crate::id3::v2::GeneralEncapsulatedObject
1316#[ derive( Clone , Eq , PartialEq ) ]
14- pub struct AttachedFile {
17+ pub struct AttachedFile < ' a > {
1518 /// A human-friendly name for the attached file.
16- pub description : Option < String > ,
19+ pub description : Option < Cow < ' a , str > > ,
1720 /// The actual file name of the attached file.
18- pub file_name : String ,
21+ pub file_name : Cow < ' a , str > ,
1922 /// Media type of the file following the [RFC6838] format.
2023 ///
2124 /// [RFC6838]: https://tools.ietf.org/html/rfc6838
2225 pub mime_type : MimeType ,
2326 /// The data of the file.
24- pub file_data : Vec < u8 > ,
27+ pub file_data : Cow < ' a , [ u8 ] > ,
2528 /// Unique ID representing the file, as random as possible.
2629 pub uid : u64 ,
2730 /// A binary value that a track/codec can refer to when the attachment is needed.
28- pub referral : Option < Vec < u8 > > ,
31+ pub referral : Option < Cow < ' a , [ u8 ] > > ,
2932 /// The timestamp at which this optimized font attachment comes into context.
3033 ///
3134 /// This is expressed in Segment Ticks which is based on `TimestampScale`. This element is
@@ -38,7 +41,7 @@ pub struct AttachedFile {
3841 pub used_end_time : Option < u64 > ,
3942}
4043
41- impl Debug for AttachedFile {
44+ impl Debug for AttachedFile < ' _ > {
4245 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
4346 f. debug_struct ( "AttachedFile" )
4447 . field ( "description" , & self . description )
@@ -53,12 +56,85 @@ impl Debug for AttachedFile {
5356 }
5457}
5558
56- impl AttachedFile {
59+ impl From < Picture > for AttachedFile < ' _ > {
60+ fn from ( picture : Picture ) -> Self {
61+ Self {
62+ description : picture. description ,
63+ file_name : picture. file_name . unwrap_or_default ( ) ,
64+ mime_type : picture
65+ . mime_type
66+ . unwrap_or ( MimeType :: Unknown ( String :: from ( "image/" ) ) ) ,
67+ file_data : picture. data ,
68+ uid : 0 ,
69+ referral : None ,
70+ used_start_time : None ,
71+ used_end_time : None ,
72+ }
73+ }
74+ }
75+
76+ impl AttachedFile < ' _ > {
77+ /// Whether this file is an image
78+ ///
79+ /// This will check if the [`MimeType`] starts with `image/`.
80+ ///
81+ /// # Examples
82+ ///
83+ /// ```rust
84+ /// use lofty::ebml::AttachedFile;
85+ /// use lofty::picture::MimeType;
86+ ///
87+ /// let file = AttachedFile {
88+ /// description: None,
89+ /// file_name: "something.png".into(),
90+ /// // PNG MIME type
91+ /// mime_type: MimeType::Png,
92+ /// file_data: vec![1, 2, 3].into(),
93+ /// uid: 0,
94+ /// referral: None,
95+ /// used_start_time: None,
96+ /// used_end_time: None
97+ /// };
98+ ///
99+ /// assert!(file.is_image());
100+ pub fn is_image ( & self ) -> bool {
101+ match & self . mime_type {
102+ MimeType :: Unknown ( mime) if mime. starts_with ( "image/" ) => true ,
103+ MimeType :: Unknown ( _) => false ,
104+ // `MimeType` is only ever used for `Picture`s outside of Matroska
105+ _ => true ,
106+ }
107+ }
108+
57109 pub ( crate ) fn validate ( & self ) -> Result < ( ) > {
58110 if self . uid == 0 {
59111 encode_err ! ( @BAIL Ebml , "The UID of an attachment cannot be 0" ) ;
60112 }
61113
62114 Ok ( ( ) )
63115 }
116+
117+ pub ( crate ) fn into_owned ( self ) -> AttachedFile < ' static > {
118+ let AttachedFile {
119+ description,
120+ file_name,
121+ mime_type,
122+ file_data,
123+ uid,
124+ referral,
125+ used_start_time,
126+ used_end_time,
127+ } = self ;
128+
129+ AttachedFile {
130+ description : description. map ( |d| Cow :: Owned ( d. into_owned ( ) ) ) ,
131+ file_name : Cow :: Owned ( file_name. into_owned ( ) ) ,
132+ mime_type,
133+ file_data : Cow :: Owned ( file_data. into_owned ( ) ) ,
134+ uid,
135+ referral : referral. map ( |r| Cow :: Owned ( r. into_owned ( ) ) ) ,
136+ used_start_time,
137+ used_end_time,
138+ }
139+ }
64140}
0 commit comments