1use crate::error::Error;
2use crate::registry::*;
3use crate::value::{sequence_size, Cursor, Value};
4use alloc::vec::Vec;
5use core::fmt::{self, Write};
6
7const MAX_DEPTH: usize = 64;
9
10pub fn to_text(value: &Value<'_>) -> Result<alloc::string::String, Error> {
12 let mut out = alloc::string::String::new();
13 fmt_value(value, &mut out, MAX_DEPTH)?;
14 Ok(out)
15}
16
17pub fn from_text(input: &str, registry: &Registry, ty_id: TypeId) -> Result<Vec<u8>, Error> {
19 let mut parser = Parser {
20 input,
21 pos: 0,
22 registry,
23 depth: MAX_DEPTH,
24 };
25 let mut out = Vec::new();
26 parser.parse_value(ty_id, &mut out)?;
27 if parser.pos != parser.input.len() {
28 let trailing = &input[parser.pos..];
29 let truncated = if trailing.len() > 40 {
30 alloc::format!("{}...", &trailing[..40])
31 } else {
32 alloc::string::String::from(trailing)
33 };
34 return Err(Error::BadInput(alloc::format!(
35 "unexpected trailing input: '{truncated}'"
36 )));
37 }
38 Ok(out)
39}
40
41impl fmt::Display for Value<'_> {
44 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45 fmt_value(self, f, MAX_DEPTH).map_err(|_| fmt::Error)
46 }
47}
48
49fn fmt_value(value: &Value<'_>, out: &mut impl Write, depth: usize) -> Result<(), Error> {
52 let depth = depth.checked_sub(1).ok_or_else(|| {
53 Error::BadInput("maximum nesting depth exceeded".into())
54 })?;
55
56 let ty = value.ty().ok_or(Error::TypeNotFound(value.ty_id))?;
57 let data = value.data;
58 let reg = value.registry;
59
60 match ty {
61 TypeDef::Bool => {
62 write!(out, "{}", value.as_bool().ok_or(Error::Eof)?)?;
63 }
64 TypeDef::U8 => write!(out, "{}", value.as_u8().ok_or(Error::Eof)?)?,
65 TypeDef::U16 => write!(out, "{}", value.as_u16().ok_or(Error::Eof)?)?,
66 TypeDef::U32 => write!(out, "{}", value.as_u32().ok_or(Error::Eof)?)?,
67 TypeDef::U64 => write!(out, "{}", value.as_u64().ok_or(Error::Eof)?)?,
68 TypeDef::U128 => write!(out, "{}", value.as_u128().ok_or(Error::Eof)?)?,
69 TypeDef::I8 => write!(out, "{}", value.as_i8().ok_or(Error::Eof)?)?,
70 TypeDef::I16 => write!(out, "{}", value.as_i16().ok_or(Error::Eof)?)?,
71 TypeDef::I32 => write!(out, "{}", value.as_i32().ok_or(Error::Eof)?)?,
72 TypeDef::I64 => write!(out, "{}", value.as_i64().ok_or(Error::Eof)?)?,
73 TypeDef::I128 => write!(out, "{}", value.as_i128().ok_or(Error::Eof)?)?,
74 TypeDef::Char => {
75 let c = value.as_char().ok_or(Error::Eof)?;
76 write!(out, "{c}")?;
77 }
78 TypeDef::Str => {
79 let s = value.as_str().ok_or(Error::Eof)?;
80 out.write_char('\'')?;
81 for c in s.chars() {
82 if c == '\'' {
83 out.write_str("''")?;
84 } else {
85 out.write_char(c)?;
86 }
87 }
88 out.write_char('\'')?;
89 }
90 TypeDef::Bytes => {
91 let (len, prefix) = sequence_size(data)?;
92 let bytes = data.get(prefix..prefix + len).ok_or(Error::Eof)?;
93 write_hex(bytes, out)?;
94 }
95 TypeDef::Compact(_) => {
96 let (val, _) = sequence_size(data)?;
97 write!(out, "{val}")?;
98 }
99 TypeDef::Tuple(tys) => {
100 out.write_char('(')?;
101 let mut cursor = Cursor::new(data, reg);
102 for (i, ty_id) in tys.iter().enumerate() {
103 if i > 0 {
104 out.write_char(';')?;
105 }
106 fmt_value(&cursor.next_value(*ty_id)?, out, depth)?;
107 }
108 out.write_char(')')?;
109 }
110 TypeDef::StructUnit => {}
111 TypeDef::StructNewType(inner) => {
112 fmt_value(&Value::new(data, *inner, reg), out, depth)?;
113 }
114 TypeDef::StructTuple(tys) => {
115 out.write_char('(')?;
116 let mut cursor = Cursor::new(data, reg);
117 for (i, ty_id) in tys.iter().enumerate() {
118 if i > 0 {
119 out.write_char(';')?;
120 }
121 fmt_value(&cursor.next_value(*ty_id)?, out, depth)?;
122 }
123 out.write_char(')')?;
124 }
125 TypeDef::Struct(fields) => {
126 out.write_char('(')?;
127 let mut cursor = Cursor::new(data, reg);
128 for (i, f) in fields.iter().enumerate() {
129 if i > 0 {
130 out.write_char(';')?;
131 }
132 out.write_str(&f.name)?;
133 out.write_char(':')?;
134 fmt_value(&cursor.next_value(f.ty)?, out, depth)?;
135 }
136 out.write_char(')')?;
137 }
138 TypeDef::Variant(vdef) => {
139 let idx = *data.first().ok_or(Error::Eof)?;
140 let var = vdef.variant(idx)?;
141 out.write_str(&vdef.name)?;
142 out.write_str("::")?;
143 out.write_str(&var.name)?;
144 let inner = &data[1..];
145 match &var.fields {
146 Fields::Unit => {}
147 Fields::NewType(ty_id) => {
148 out.write_char('(')?;
149 fmt_value(&Value::new(inner, *ty_id, reg), out, depth)?;
150 out.write_char(')')?;
151 }
152 Fields::Tuple(tys) => {
153 out.write_char('(')?;
154 let mut cursor = Cursor::new(inner, reg);
155 for (i, ty_id) in tys.iter().enumerate() {
156 if i > 0 {
157 out.write_char(';')?;
158 }
159 fmt_value(&cursor.next_value(*ty_id)?, out, depth)?;
160 }
161 out.write_char(')')?;
162 }
163 Fields::Struct(fields) => {
164 out.write_char('(')?;
165 let mut cursor = Cursor::new(inner, reg);
166 for (i, f) in fields.iter().enumerate() {
167 if i > 0 {
168 out.write_char(';')?;
169 }
170 out.write_str(&f.name)?;
171 out.write_char(':')?;
172 fmt_value(&cursor.next_value(f.ty)?, out, depth)?;
173 }
174 out.write_char(')')?;
175 }
176 }
177 }
178 TypeDef::Sequence(inner_ty) => {
179 let (len, prefix) = sequence_size(data)?;
180 out.write_str("..")?;
181 let mut cursor = Cursor::new(&data[prefix..], reg);
182 for i in 0..len {
183 if i > 0 {
184 out.write_char(';')?;
185 }
186 fmt_value(&cursor.next_value(*inner_ty)?, out, depth)?;
187 }
188 out.write_char('.')?;
189 }
190 TypeDef::Array(inner_ty, len) => {
191 out.write_str("..")?;
192 let mut cursor = Cursor::new(data, reg);
193 for i in 0..*len {
194 if i > 0 {
195 out.write_char(';')?;
196 }
197 fmt_value(&cursor.next_value(*inner_ty)?, out, depth)?;
198 }
199 out.write_char('.')?;
200 }
201 TypeDef::Map(ty_k, ty_v) => {
202 let (len, prefix) = sequence_size(data)?;
203 out.write_str("..")?;
204 let mut cursor = Cursor::new(&data[prefix..], reg);
205 for i in 0..len {
206 if i > 0 {
207 out.write_char(';')?;
208 }
209 out.write_char('(')?;
210 fmt_value(&cursor.next_value(*ty_k)?, out, depth)?;
211 out.write_char(';')?;
212 fmt_value(&cursor.next_value(*ty_v)?, out, depth)?;
213 out.write_char(')')?;
214 }
215 out.write_char('.')?;
216 }
217 TypeDef::BitSequence(_, _) => {
218 let (bit_len, prefix) = sequence_size(data)?;
219 let byte_len = bit_len.div_ceil(8);
220 let bytes = data.get(prefix..prefix + byte_len).ok_or(Error::Eof)?;
221 write_hex(bytes, out)?;
222 }
223 }
224 Ok(())
225}
226
227fn write_hex(bytes: &[u8], out: &mut impl Write) -> fmt::Result {
230 out.write_str("0x")?;
231 for &b in bytes {
232 write!(out, "{:02x}", b)?;
233 }
234 Ok(())
235}
236
237fn is_delimiter(c: char) -> bool {
240 matches!(c, ';' | ')' | '.' | ':' | '(')
241}
242
243struct Parser<'a> {
246 input: &'a str,
247 pos: usize,
248 registry: &'a Registry,
249 depth: usize,
250}
251
252impl<'a> Parser<'a> {
253 fn remaining(&self) -> &'a str {
254 &self.input[self.pos..]
255 }
256
257 fn peek(&self) -> Option<char> {
258 self.remaining().chars().next()
259 }
260
261 fn advance(&mut self, n: usize) {
262 self.pos += n;
263 }
264
265 fn expect(&mut self, c: char) -> Result<(), Error> {
266 if self.peek() == Some(c) {
267 self.advance(c.len_utf8());
268 Ok(())
269 } else {
270 Err(Error::BadInput(alloc::format!(
271 "expected '{}' at position {}",
272 c, self.pos
273 )))
274 }
275 }
276
277 fn consume(&mut self, s: &str) -> bool {
278 if self.remaining().starts_with(s) {
279 self.advance(s.len());
280 true
281 } else {
282 false
283 }
284 }
285
286 fn take_while(&mut self, pred: impl Fn(char) -> bool) -> &'a str {
287 let start = self.pos;
288 while self.peek().is_some_and(&pred) {
289 self.advance(self.peek().unwrap().len_utf8());
290 }
291 &self.input[start..self.pos]
292 }
293
294 fn at_seq_close(&self) -> bool {
296 let r = self.remaining();
297 r.starts_with('.') && !r.starts_with("..")
298 }
299
300 fn expect_delimiter(&self) -> Result<(), Error> {
303 match self.peek() {
304 None => Ok(()),
305 Some(c) if is_delimiter(c) => Ok(()),
306 Some(c) => Err(Error::BadInput(alloc::format!(
307 "unexpected character '{c}' at position {}",
308 self.pos
309 ))),
310 }
311 }
312
313 fn parse_uint(&mut self) -> Result<u128, Error> {
314 let s = self.take_while(|c| c.is_ascii_digit());
315 if s.is_empty() {
316 return Err(Error::BadInput(alloc::format!(
317 "expected number at position {}",
318 self.pos
319 )));
320 }
321 s.parse::<u128>()
322 .map_err(|e| Error::BadInput(alloc::string::ToString::to_string(&e)))
323 }
324
325 fn parse_uint_checked<T: TryFrom<u128>>(&mut self) -> Result<T, Error> {
326 let n = self.parse_uint()?;
327 T::try_from(n).map_err(|_| Error::BadInput(alloc::format!("{n} out of range")))
328 }
329
330 fn parse_int(&mut self) -> Result<i128, Error> {
331 let neg = self.consume("-");
332 let n = self.parse_uint()?;
333 let n = n as i128;
334 Ok(if neg { -n } else { n })
335 }
336
337 fn parse_int_checked<T: TryFrom<i128>>(&mut self) -> Result<T, Error> {
338 let n = self.parse_int()?;
339 T::try_from(n).map_err(|_| Error::BadInput(alloc::format!("{n} out of range")))
340 }
341
342 fn parse_hex_bytes(&mut self) -> Result<Vec<u8>, Error> {
343 if !self.consume("0x") {
344 return Err(Error::BadInput("expected '0x' prefix".into()));
345 }
346 let hex_str = self.take_while(|c| c.is_ascii_hexdigit());
347 crate::decode_hex(hex_str)
348 }
349
350 fn parse_value(&mut self, ty_id: TypeId, out: &mut Vec<u8>) -> Result<(), Error> {
351 self.depth = self.depth.checked_sub(1).ok_or_else(|| {
352 Error::BadInput("maximum nesting depth exceeded".into())
353 })?;
354
355 let result = self.parse_value_inner(ty_id, out);
356
357 self.depth += 1;
358 result
359 }
360
361 fn parse_value_inner(&mut self, ty_id: TypeId, out: &mut Vec<u8>) -> Result<(), Error> {
362 let reg = self.registry;
363 let ty = reg.resolve(ty_id).ok_or(Error::TypeNotFound(ty_id))?;
364
365 match ty {
366 TypeDef::Bool => {
367 if self.consume("true") {
368 self.expect_delimiter()?;
369 out.push(1);
370 } else if self.consume("false") {
371 self.expect_delimiter()?;
372 out.push(0);
373 } else {
374 return Err(Error::BadInput("expected 'true' or 'false'".into()));
375 }
376 }
377 TypeDef::U8 => {
378 let n: u8 = self.parse_uint_checked()?;
379 out.push(n);
380 }
381 TypeDef::U16 => {
382 let n: u16 = self.parse_uint_checked()?;
383 out.extend_from_slice(&n.to_le_bytes());
384 }
385 TypeDef::U32 => {
386 let n: u32 = self.parse_uint_checked()?;
387 out.extend_from_slice(&n.to_le_bytes());
388 }
389 TypeDef::U64 => {
390 let n: u64 = self.parse_uint_checked()?;
391 out.extend_from_slice(&n.to_le_bytes());
392 }
393 TypeDef::U128 => {
394 let n = self.parse_uint()?;
395 out.extend_from_slice(&n.to_le_bytes());
396 }
397 TypeDef::I8 => {
398 let n: i8 = self.parse_int_checked()?;
399 out.push(n as u8);
400 }
401 TypeDef::I16 => {
402 let n: i16 = self.parse_int_checked()?;
403 out.extend_from_slice(&n.to_le_bytes());
404 }
405 TypeDef::I32 => {
406 let n: i32 = self.parse_int_checked()?;
407 out.extend_from_slice(&n.to_le_bytes());
408 }
409 TypeDef::I64 => {
410 let n: i64 = self.parse_int_checked()?;
411 out.extend_from_slice(&n.to_le_bytes());
412 }
413 TypeDef::I128 => {
414 let n = self.parse_int()?;
415 out.extend_from_slice(&n.to_le_bytes());
416 }
417 TypeDef::Char => {
418 let c = self.peek().ok_or(Error::Eof)?;
419 self.advance(c.len_utf8());
420 out.extend_from_slice(&(c as u32).to_le_bytes());
421 }
422 TypeDef::Str => {
423 self.expect('\'')?;
424 let mut s = Vec::new();
426 loop {
427 match self.peek() {
428 None => return Err(Error::BadInput("unterminated string".into())),
429 Some('\'') => {
430 self.advance(1);
431 if self.peek() == Some('\'') {
433 self.advance(1);
434 s.push(b'\'');
435 } else {
436 break;
437 }
438 }
439 Some(c) => {
440 self.advance(c.len_utf8());
441 let mut buf = [0u8; 4];
442 s.extend_from_slice(c.encode_utf8(&mut buf).as_bytes());
443 }
444 }
445 }
446 crate::compact_encode(s.len() as u128, &mut *out);
447 out.extend_from_slice(&s);
448 }
449 TypeDef::Bytes => {
450 let bytes = self.parse_hex_bytes()?;
451 crate::compact_encode(bytes.len() as u128, &mut *out);
452 out.extend_from_slice(&bytes);
453 }
454 TypeDef::Compact(_) => {
455 let n = self.parse_uint()?;
456 crate::compact_encode(n, out);
457 }
458 TypeDef::Tuple(tys) => {
459 self.expect('(')?;
460 for (i, ty_id) in tys.iter().enumerate() {
461 if i > 0 {
462 self.expect(';')?;
463 }
464 self.parse_value(*ty_id, out)?;
465 }
466 self.expect(')')?;
467 }
468 TypeDef::StructUnit => {}
469 TypeDef::StructNewType(inner) => {
470 let inner = *inner;
471 self.parse_value(inner, out)?;
472 }
473 TypeDef::StructTuple(tys) => {
474 self.expect('(')?;
475 for (i, ty_id) in tys.iter().enumerate() {
476 if i > 0 {
477 self.expect(';')?;
478 }
479 self.parse_value(*ty_id, out)?;
480 }
481 self.expect(')')?;
482 }
483 TypeDef::Struct(fields) => {
484 self.expect('(')?;
485 for (i, f) in fields.iter().enumerate() {
486 if i > 0 {
487 self.expect(';')?;
488 }
489 if !self.consume(&f.name) {
490 return Err(Error::BadInput(alloc::format!(
491 "expected field '{}'",
492 f.name
493 )));
494 }
495 self.expect(':')?;
496 self.parse_value(f.ty, out)?;
497 }
498 self.expect(')')?;
499 }
500 TypeDef::Variant(vdef) => {
501 if !self.remaining().starts_with(vdef.name.as_str()) {
502 return Err(Error::BadInput(alloc::format!(
503 "expected enum '{}'",
504 vdef.name
505 )));
506 }
507 self.advance(vdef.name.len());
508 self.expect(':')?;
509 self.expect(':')?;
510 let var_name = self.take_while(|c| c.is_alphanumeric() || c == '_');
511 let var = vdef
512 .variants
513 .iter()
514 .find(|v| v.name == var_name)
515 .ok_or_else(|| {
516 Error::BadInput(alloc::format!("unknown variant '{var_name}'"))
517 })?;
518 out.push(var.index);
519 match &var.fields {
520 Fields::Unit => {}
521 Fields::NewType(ty_id) => {
522 self.expect('(')?;
523 self.parse_value(*ty_id, out)?;
524 self.expect(')')?;
525 }
526 Fields::Tuple(tys) => {
527 self.expect('(')?;
528 for (i, ty_id) in tys.iter().enumerate() {
529 if i > 0 {
530 self.expect(';')?;
531 }
532 self.parse_value(*ty_id, out)?;
533 }
534 self.expect(')')?;
535 }
536 Fields::Struct(fields) => {
537 self.expect('(')?;
538 for (i, f) in fields.iter().enumerate() {
539 if i > 0 {
540 self.expect(';')?;
541 }
542 if !self.consume(&f.name) {
543 return Err(Error::BadInput(alloc::format!(
544 "expected field '{}'",
545 f.name
546 )));
547 }
548 self.expect(':')?;
549 self.parse_value(f.ty, out)?;
550 }
551 self.expect(')')?;
552 }
553 }
554 }
555 TypeDef::Sequence(inner_ty) => {
556 let inner_ty = *inner_ty;
557 if !self.consume("..") {
558 return Err(Error::BadInput("expected '..' for sequence".into()));
559 }
560 let mut items = Vec::new();
561 let mut count = 0usize;
562 if !self.at_seq_close() {
563 loop {
564 self.parse_value(inner_ty, &mut items)?;
565 count += 1;
566 if !self.consume(";") || self.at_seq_close() {
567 break;
568 }
569 }
570 }
571 self.expect('.')?;
572 crate::compact_encode(count as u128, &mut *out);
573 out.extend_from_slice(&items);
574 }
575 TypeDef::Array(inner_ty, len) => {
576 let (inner_ty, len) = (*inner_ty, *len);
577 if !self.consume("..") {
578 return Err(Error::BadInput("expected '..' for array".into()));
579 }
580 for i in 0..len {
581 if i > 0 {
582 self.expect(';')?;
583 }
584 self.parse_value(inner_ty, out)?;
585 }
586 self.expect('.')?;
587 }
588 TypeDef::Map(ty_k, ty_v) => {
589 let (ty_k, ty_v) = (*ty_k, *ty_v);
590 if !self.consume("..") {
591 return Err(Error::BadInput("expected '..' for map".into()));
592 }
593 let mut items = Vec::new();
594 let mut count = 0usize;
595 if !self.at_seq_close() {
596 loop {
597 self.expect('(')?;
598 self.parse_value(ty_k, &mut items)?;
599 self.expect(';')?;
600 self.parse_value(ty_v, &mut items)?;
601 self.expect(')')?;
602 count += 1;
603 if !self.consume(";") || self.at_seq_close() {
604 break;
605 }
606 }
607 }
608 self.expect('.')?;
609 crate::compact_encode(count as u128, &mut *out);
610 out.extend_from_slice(&items);
611 }
612 TypeDef::BitSequence(_, _) => {
613 let bytes = self.parse_hex_bytes()?;
614 let bit_len = bytes.len() * 8;
615 crate::compact_encode(bit_len as u128, &mut *out);
616 out.extend_from_slice(&bytes);
617 }
618 }
619 Ok(())
620 }
621}