1+ use std:: borrow:: Cow ;
2+
13use crate :: tag:: ItemValue ;
24
35/// The language of a [`SimpleTag`] or chapter
@@ -35,27 +37,72 @@ pub enum Language {
3537/// - [`ItemValue::Text`] | [`ItemValue::Locator`] -> [`TagValue::String`]
3638/// - [`ItemValue::Binary`] -> [`TagValue::Binary`]
3739#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
38- pub enum TagValue {
40+ pub enum TagValue < ' a > {
3941 /// A UTF-8 string tag value
40- String ( String ) ,
42+ String ( Cow < ' a , str > ) ,
4143 /// A binary tag value
42- Binary ( Vec < u8 > ) ,
44+ Binary ( Cow < ' a , [ u8 ] > ) ,
4345}
4446
45- impl From < TagValue > for ItemValue {
46- fn from ( value : TagValue ) -> Self {
47+ impl From < TagValue < ' _ > > for ItemValue {
48+ fn from ( value : TagValue < ' _ > ) -> Self {
4749 match value {
48- TagValue :: String ( s) => ItemValue :: Text ( s) ,
49- TagValue :: Binary ( b) => ItemValue :: Binary ( b) ,
50+ TagValue :: String ( s) => ItemValue :: Text ( s. into_owned ( ) ) ,
51+ TagValue :: Binary ( b) => ItemValue :: Binary ( b. into_owned ( ) ) ,
5052 }
5153 }
5254}
5355
54- impl From < ItemValue > for TagValue {
56+ impl From < ItemValue > for TagValue < ' _ > {
5557 fn from ( value : ItemValue ) -> Self {
5658 match value {
57- ItemValue :: Text ( s) | ItemValue :: Locator ( s) => TagValue :: String ( s) ,
58- ItemValue :: Binary ( b) => TagValue :: Binary ( b) ,
59+ ItemValue :: Text ( s) | ItemValue :: Locator ( s) => TagValue :: String ( Cow :: Owned ( s) ) ,
60+ ItemValue :: Binary ( b) => TagValue :: Binary ( Cow :: Owned ( b) ) ,
61+ }
62+ }
63+ }
64+
65+ impl From < String > for TagValue < ' _ > {
66+ fn from ( value : String ) -> Self {
67+ TagValue :: String ( value. into ( ) )
68+ }
69+ }
70+
71+ impl < ' a > From < Cow < ' a , str > > for TagValue < ' a > {
72+ fn from ( value : Cow < ' a , str > ) -> Self {
73+ TagValue :: String ( value)
74+ }
75+ }
76+
77+ impl < ' a > From < & ' a str > for TagValue < ' a > {
78+ fn from ( value : & ' a str ) -> Self {
79+ TagValue :: String ( Cow :: Borrowed ( value) )
80+ }
81+ }
82+
83+ impl From < Vec < u8 > > for TagValue < ' _ > {
84+ fn from ( value : Vec < u8 > ) -> Self {
85+ TagValue :: Binary ( value. into ( ) )
86+ }
87+ }
88+
89+ impl < ' a > From < Cow < ' a , [ u8 ] > > for TagValue < ' a > {
90+ fn from ( value : Cow < ' a , [ u8 ] > ) -> Self {
91+ TagValue :: Binary ( value)
92+ }
93+ }
94+
95+ impl < ' a > From < & ' a [ u8 ] > for TagValue < ' a > {
96+ fn from ( value : & ' a [ u8 ] ) -> Self {
97+ TagValue :: Binary ( Cow :: Borrowed ( value) )
98+ }
99+ }
100+
101+ impl TagValue < ' _ > {
102+ fn into_owned ( self ) -> TagValue < ' static > {
103+ match self {
104+ TagValue :: String ( s) => TagValue :: String ( Cow :: Owned ( s. into_owned ( ) ) ) ,
105+ TagValue :: Binary ( b) => TagValue :: Binary ( Cow :: Owned ( b. into_owned ( ) ) ) ,
59106 }
60107 }
61108}
@@ -69,7 +116,7 @@ impl From<ItemValue> for TagValue {
69116/// - This also means that multiple tags can describe the same target.
70117/// - They **do not** need to have a value.
71118#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
72- pub struct SimpleTag {
119+ pub struct SimpleTag < ' a > {
73120 /// The name of the tag as it is stored
74121 ///
75122 /// This field can essentially contain anything, but the following conditions are recommended:
@@ -78,12 +125,12 @@ pub struct SimpleTag {
78125 /// - It **SHOULD NOT** contain any space.
79126 ///
80127 /// When in doubt, the [`TagName`] enum can be used, which covers all specified tags.
81- pub name : String ,
128+ pub name : Cow < ' a , str > ,
82129 /// The language of the tag
83130 ///
84131 /// See [`Language`] for more information.
85132 pub language : Option < Language > ,
86- /// Whether [`language`] is the default/original langauge to use
133+ /// Whether [`language`] is the default/original language to use
87134 ///
88135 /// This is used when multiple languages are present in a file. This field will be ignored
89136 /// if [`language`] is `None`.
@@ -93,5 +140,38 @@ pub struct SimpleTag {
93140 /// The actual tag value
94141 ///
95142 /// For more information, see [`TagValue`]
96- pub value : Option < TagValue > ,
143+ pub value : Option < TagValue < ' a > > ,
144+ }
145+
146+ impl < ' a > SimpleTag < ' a > {
147+ /// Create a new `SimpleTag` with the given name and value
148+ ///
149+ /// # Example
150+ ///
151+ /// ```
152+ /// use lofty::ebml::{SimpleTag, TagValue};
153+ ///
154+ /// let tag = SimpleTag::new("TITLE", "My Title");
155+ /// ```
156+ pub fn new < N , V > ( name : N , value : V ) -> Self
157+ where
158+ N : Into < Cow < ' a , str > > ,
159+ V : Into < TagValue < ' a > > ,
160+ {
161+ Self {
162+ name : name. into ( ) ,
163+ language : None ,
164+ default : false ,
165+ value : Some ( value. into ( ) ) ,
166+ }
167+ }
168+
169+ pub ( crate ) fn into_owned ( self ) -> SimpleTag < ' static > {
170+ SimpleTag {
171+ name : Cow :: Owned ( self . name . into_owned ( ) ) ,
172+ language : self . language ,
173+ default : self . default ,
174+ value : self . value . map ( TagValue :: into_owned) ,
175+ }
176+ }
97177}
0 commit comments