1- use super :: { COLOR , Component , Content , Style , TEXT , TRANSLATE } ;
2- use crate :: chat:: { TRANSLATE_FALLBACK , TRANSLATE_WITH , TextColor } ;
1+ use super :: {
2+ COLOR , Component , Content , SCORE , SCORE_NAME , SCORE_OBJECTIVE , Style , TEXT , TRANSLATE ,
3+ TRANSLATE_FALLBACK , TRANSLATE_WITH , TYPE , TextColor ,
4+ } ;
35use crate :: nbt:: { ListInfo , StringTag , StringTagRaw , StringTagWriter , TagType } ;
46use crate :: str:: SmolStr ;
57use alloc:: alloc:: Allocator ;
68use alloc:: vec:: Vec ;
79use mser:: { Error , Read , UnsafeWriter , Write } ;
810
11+ const fn content_type < A : Allocator > ( content : & Content < A > ) -> & ' static [ u8 ] {
12+ match content {
13+ Content :: Literal { .. } => b"text" ,
14+ Content :: Translatable { .. } => b"translatable" ,
15+ Content :: Score { .. } => b"score" ,
16+ Content :: Selector { .. } => b"selector" ,
17+ Content :: Keybind { .. } => b"keybind" ,
18+ Content :: BlockNbt { .. } | Content :: EntityNbt { .. } | Content :: StorageNbt { .. } => b"nbt" ,
19+ Content :: Object { .. } => b"object" ,
20+ }
21+ }
22+
923unsafe fn write_raw < A : Allocator > (
1024 content : & Content < A > ,
1125 style : & Style < A > ,
1226 children : & [ Component < A > ] ,
1327 w : & mut UnsafeWriter ,
1428) {
29+ unsafe {
30+ TagType :: String . write ( w) ;
31+ StringTagRaw :: new_unchecked ( TYPE ) . write ( w) ;
32+ StringTagRaw :: new_unchecked ( content_type ( content) ) . write ( w) ;
33+ }
1534 match content {
1635 Content :: Literal { content } => unsafe {
1736 TagType :: String . write ( w) ;
@@ -46,7 +65,38 @@ unsafe fn write_raw<A: Allocator>(
4665 }
4766 }
4867 } ,
49- _ => { }
68+ Content :: Score { name, objective } => unsafe {
69+ TagType :: Compound . write ( w) ;
70+ StringTagRaw :: new_unchecked ( SCORE ) . write ( w) ;
71+ TagType :: String . write ( w) ;
72+ StringTagRaw :: new_unchecked ( SCORE_NAME ) . write ( w) ;
73+ StringTagWriter ( name) . write ( w) ;
74+ TagType :: String . write ( w) ;
75+ StringTagRaw :: new_unchecked ( SCORE_OBJECTIVE ) . write ( w) ;
76+ StringTagWriter ( objective) . write ( w) ;
77+ TagType :: End . write ( w) ;
78+ } ,
79+ Content :: Selector { pattern, separator } => { }
80+ Content :: Keybind { keybind } => { }
81+ Content :: BlockNbt {
82+ nbt_path,
83+ interpret,
84+ separator,
85+ pos,
86+ } => { }
87+ Content :: EntityNbt {
88+ nbt_path,
89+ interpret,
90+ separator,
91+ selector,
92+ } => { }
93+ Content :: StorageNbt {
94+ nbt_path,
95+ interpret,
96+ separator,
97+ storage,
98+ } => { }
99+ Content :: Object { contents } => { }
50100 }
51101 unsafe {
52102 if let Some ( color) = style. color {
@@ -65,6 +115,9 @@ fn write_raw_len<A: Allocator>(
65115 children : & [ Component < A > ] ,
66116) -> usize {
67117 let mut w = 0usize ;
118+ w += TagType :: String . sz ( ) ;
119+ w += StringTagRaw :: new_unchecked ( TYPE ) . sz ( ) ;
120+ w += StringTagRaw :: new_unchecked ( content_type ( content) ) . sz ( ) ;
68121 match content {
69122 Content :: Literal { content } => {
70123 w += TagType :: String . sz ( ) ;
@@ -99,6 +152,17 @@ fn write_raw_len<A: Allocator>(
99152 }
100153 }
101154 }
155+ Content :: Score { name, objective } => {
156+ w += TagType :: Compound . sz ( ) ;
157+ w += StringTagRaw :: new_unchecked ( SCORE ) . sz ( ) ;
158+ w += TagType :: String . sz ( ) ;
159+ w += StringTagRaw :: new_unchecked ( SCORE_NAME ) . sz ( ) ;
160+ w += StringTagWriter ( name) . sz ( ) ;
161+ w += TagType :: String . sz ( ) ;
162+ w += StringTagRaw :: new_unchecked ( SCORE_OBJECTIVE ) . sz ( ) ;
163+ w += StringTagWriter ( objective) . sz ( ) ;
164+ w += TagType :: End . sz ( ) ;
165+ }
102166 _ => { }
103167 } ;
104168 if let Some ( color) = style. color {
@@ -117,137 +181,141 @@ fn read_raw(buf: &mut &[u8]) -> Result<Component, Error> {
117181 let mut style = Style :: new ( ) ;
118182 let children = Vec :: new ( ) ;
119183 loop {
120- let tag_type = TagType :: read ( buf) ?;
121- if tag_type == TagType :: End {
122- return Ok ( Component {
123- content : match content {
124- Some ( x ) => x ,
125- None => Content :: Literal {
126- content : SmolStr :: EMPTY ,
184+ let t1 = TagType :: read ( buf) ?;
185+ macro_rules! expect_str {
186+ ( $ty : expr ) => {
187+ match $ty {
188+ TagType :: String => match StringTag :: read ( buf ) {
189+ Ok ( x ) => x . 0 ,
190+ Err ( e ) => return Err ( e ) ,
127191 } ,
192+ _ => return Err ( Error ) ,
193+ }
194+ } ;
195+ }
196+ if t1 == TagType :: End {
197+ let content = match content {
198+ Some ( x) => x,
199+ None => Content :: Literal {
200+ content : SmolStr :: EMPTY ,
128201 } ,
202+ } ;
203+ return Ok ( Component {
204+ content,
129205 style,
130206 children,
131207 } ) ;
132208 }
133- let name = StringTag :: read ( buf) ?;
134- let name = name. 0 . as_str ( ) ;
135- match name. as_bytes ( ) {
209+ match StringTag :: read ( buf) ?. 0 . as_bytes ( ) {
136210 TEXT => {
137- match & content {
138- None => {
139- content = Some ( Content :: Literal {
140- content : SmolStr :: EMPTY ,
141- } )
142- }
143- Some ( Content :: Literal { .. } ) => { }
144- _ => return Err ( Error ) ,
211+ if content. is_none ( ) {
212+ content = Some ( Content :: Literal {
213+ content : SmolStr :: EMPTY ,
214+ } )
145215 }
146- match content. as_mut ( ) {
147- Some ( Content :: Literal { content } ) => match tag_type {
148- TagType :: String => {
149- * content = StringTag :: read ( buf) ?. 0 ;
150- }
151- _ => return Err ( Error ) ,
152- } ,
153- _ => return Err ( Error ) ,
216+ if let Some ( Content :: Literal { content } ) = content. as_mut ( ) {
217+ * content = expect_str ! ( t1) ;
154218 }
155219 }
156220 TRANSLATE => {
157- match & content {
158- None => {
159- content = Some ( Content :: Translatable {
160- key : SmolStr :: EMPTY ,
161- fallback : None ,
162- args : Vec :: new ( ) ,
163- } )
164- }
165- Some ( Content :: Translatable { .. } ) => { }
166- _ => return Err ( Error ) ,
167- } ;
168- match content. as_mut ( ) {
169- Some ( Content :: Translatable {
170- key,
171- fallback : _,
172- args : _,
173- } ) => match tag_type {
174- TagType :: String => {
175- * key = StringTag :: read ( buf) ?. 0 ;
176- }
177- _ => return Err ( Error ) ,
178- } ,
179- _ => return Err ( Error ) ,
221+ if content. is_none ( ) {
222+ content = Some ( Content :: Translatable {
223+ key : SmolStr :: EMPTY ,
224+ fallback : None ,
225+ args : Vec :: new ( ) ,
226+ } ) ;
227+ }
228+ if let Some ( Content :: Translatable {
229+ key,
230+ fallback : _,
231+ args : _,
232+ } ) = content. as_mut ( )
233+ {
234+ * key = expect_str ! ( t1) ;
180235 }
181236 }
182237 TRANSLATE_FALLBACK => {
183- match & content {
184- None => {
185- content = Some ( Content :: Translatable {
186- key : SmolStr :: EMPTY ,
187- fallback : None ,
188- args : Vec :: new ( ) ,
189- } )
190- }
191- Some ( Content :: Translatable { .. } ) => { }
192- _ => return Err ( Error ) ,
193- } ;
194- match content. as_mut ( ) {
195- Some ( Content :: Translatable {
196- key : _,
197- fallback,
198- args : _,
199- } ) => match tag_type {
200- TagType :: String => {
201- * fallback = Some ( StringTag :: read ( buf) ?. 0 ) ;
202- }
203- _ => return Err ( Error ) ,
204- } ,
205- _ => return Err ( Error ) ,
238+ if content. is_none ( ) {
239+ content = Some ( Content :: Translatable {
240+ key : SmolStr :: EMPTY ,
241+ fallback : None ,
242+ args : Vec :: new ( ) ,
243+ } ) ;
244+ }
245+ if let Some ( Content :: Translatable {
246+ key : _,
247+ fallback,
248+ args : _,
249+ } ) = content. as_mut ( )
250+ {
251+ * fallback = Some ( expect_str ! ( t1) ) ;
206252 }
207253 }
208254 TRANSLATE_WITH => {
209- match & content {
210- None => {
211- content = Some ( Content :: Translatable {
212- key : SmolStr :: EMPTY ,
213- fallback : None ,
214- args : Vec :: new ( ) ,
215- } )
216- }
217- Some ( Content :: Translatable { .. } ) => { }
218- _ => return Err ( Error ) ,
219- } ;
220- match content. as_mut ( ) {
221- Some ( Content :: Translatable {
222- key : _,
223- fallback : _,
224- args,
225- } ) => match tag_type {
255+ if content. is_none ( ) {
256+ content = Some ( Content :: Translatable {
257+ key : SmolStr :: EMPTY ,
258+ fallback : None ,
259+ args : Vec :: new ( ) ,
260+ } ) ;
261+ }
262+ if let Some ( Content :: Translatable {
263+ key : _,
264+ fallback : _,
265+ args,
266+ } ) = content. as_mut ( )
267+ {
268+ match t1 {
226269 TagType :: List => match ListInfo :: read ( buf) ? {
227270 ListInfo ( TagType :: Compound , len) => {
228- let mut vec = Vec :: new ( ) ;
229271 for _ in 0 ..len {
230- vec . push ( read_raw ( buf) ?) ;
272+ args . push ( read_raw ( buf) ?) ;
231273 }
232- * args = vec;
233274 }
234275 _ => return Err ( Error ) ,
235276 } ,
236277 _ => return Err ( Error ) ,
237- } ,
238- _ => return Err ( Error ) ,
278+ }
239279 }
240280 }
241- COLOR => match tag_type {
242- TagType :: String => {
243- let color = StringTag :: read ( buf) ?. 0 ;
244- style. color = match TextColor :: parse ( color. as_bytes ( ) ) {
245- Some ( x) => Some ( x) ,
246- None => return Err ( Error ) ,
247- } ;
281+ SCORE => {
282+ if content. is_none ( ) {
283+ content = Some ( Content :: Score {
284+ name : SmolStr :: EMPTY ,
285+ objective : SmolStr :: EMPTY ,
286+ } ) ;
287+ }
288+ if let Some ( Content :: Score { name, objective } ) = content. as_mut ( ) {
289+ match t1 {
290+ TagType :: Compound => loop {
291+ let t2 = TagType :: read ( buf) ?;
292+ if t2 == TagType :: End {
293+ break ;
294+ }
295+ match StringTag :: read ( buf) ?. 0 . as_bytes ( ) {
296+ SCORE_NAME => {
297+ * name = expect_str ! ( t2) ;
298+ }
299+ SCORE_OBJECTIVE => {
300+ * objective = expect_str ! ( t2) ;
301+ }
302+ _ => return Err ( Error ) ,
303+ }
304+ } ,
305+ _ => return Err ( Error ) ,
306+ }
248307 }
249- _ => return Err ( Error ) ,
250- } ,
308+ }
309+ COLOR => {
310+ let color = expect_str ! ( t1) ;
311+ style. color = match TextColor :: parse ( color. as_bytes ( ) ) {
312+ Some ( x) => Some ( x) ,
313+ None => return Err ( Error ) ,
314+ } ;
315+ }
316+ TYPE => {
317+ expect_str ! ( t1) ;
318+ }
251319 _ => return Err ( Error ) ,
252320 }
253321 }
0 commit comments