1
+ use std:: borrow:: Cow ;
2
+
1
3
use crate :: tag:: ItemValue ;
2
4
3
5
/// The language of a [`SimpleTag`] or chapter
@@ -35,27 +37,72 @@ pub enum Language {
35
37
/// - [`ItemValue::Text`] | [`ItemValue::Locator`] -> [`TagValue::String`]
36
38
/// - [`ItemValue::Binary`] -> [`TagValue::Binary`]
37
39
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
38
- pub enum TagValue {
40
+ pub enum TagValue < ' a > {
39
41
/// A UTF-8 string tag value
40
- String ( String ) ,
42
+ String ( Cow < ' a , str > ) ,
41
43
/// A binary tag value
42
- Binary ( Vec < u8 > ) ,
44
+ Binary ( Cow < ' a , [ u8 ] > ) ,
43
45
}
44
46
45
- impl From < TagValue > for ItemValue {
46
- fn from ( value : TagValue ) -> Self {
47
+ impl From < TagValue < ' _ > > for ItemValue {
48
+ fn from ( value : TagValue < ' _ > ) -> Self {
47
49
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 ( ) ) ,
50
52
}
51
53
}
52
54
}
53
55
54
- impl From < ItemValue > for TagValue {
56
+ impl From < ItemValue > for TagValue < ' _ > {
55
57
fn from ( value : ItemValue ) -> Self {
56
58
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 ( ) ) ) ,
59
106
}
60
107
}
61
108
}
@@ -69,7 +116,7 @@ impl From<ItemValue> for TagValue {
69
116
/// - This also means that multiple tags can describe the same target.
70
117
/// - They **do not** need to have a value.
71
118
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
72
- pub struct SimpleTag {
119
+ pub struct SimpleTag < ' a > {
73
120
/// The name of the tag as it is stored
74
121
///
75
122
/// This field can essentially contain anything, but the following conditions are recommended:
@@ -78,12 +125,12 @@ pub struct SimpleTag {
78
125
/// - It **SHOULD NOT** contain any space.
79
126
///
80
127
/// When in doubt, the [`TagName`] enum can be used, which covers all specified tags.
81
- pub name : String ,
128
+ pub name : Cow < ' a , str > ,
82
129
/// The language of the tag
83
130
///
84
131
/// See [`Language`] for more information.
85
132
pub language : Option < Language > ,
86
- /// Whether [`language`] is the default/original langauge to use
133
+ /// Whether [`language`] is the default/original language to use
87
134
///
88
135
/// This is used when multiple languages are present in a file. This field will be ignored
89
136
/// if [`language`] is `None`.
@@ -93,5 +140,38 @@ pub struct SimpleTag {
93
140
/// The actual tag value
94
141
///
95
142
/// 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
+ }
97
177
}
0 commit comments