1use std::{io, iter::Map};
3
4use smallvec::SmallVec;
5
6use crate::AsciiControl;
7
8fn fmt_utf8_bytes_with_ascii_control(
10 f: &mut std::fmt::Formatter<'_>,
11 bytes: &[u8],
12) -> std::fmt::Result {
13 for chunk in bytes.utf8_chunks() {
14 for c in chunk.valid().chars() {
15 if let Ok(c) = AsciiControl::try_from(c) {
16 write!(f, "{c}")?;
17 } else {
18 write!(f, "{c}")?;
19 }
20 }
21 if !chunk.invalid().is_empty() {
22 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
23 }
24 }
25 Ok(())
26}
27
28fn fmt_utf8_bytes_simple(f: &mut std::fmt::Formatter<'_>, bytes: &[u8]) -> std::fmt::Result {
30 for chunk in bytes.utf8_chunks() {
31 write!(f, "{}", chunk.valid())?;
32 if !chunk.invalid().is_empty() {
33 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
34 }
35 }
36 Ok(())
37}
38
39#[cfg_attr(feature = "serde", derive(serde::Serialize))]
40#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
41pub struct VTIntermediate {
42 pub(crate) data: [u8; 2],
43}
44
45impl VTIntermediate {
46 pub const fn empty() -> Self {
47 Self { data: [0, 0] }
48 }
49
50 pub const fn one(c: u8) -> Self {
51 assert!(c >= 0x20 && c <= 0x2F);
52 Self { data: [c, 0] }
53 }
54
55 pub const fn two(c1: u8, c2: u8) -> Self {
56 assert!(c1 >= 0x20 && c1 <= 0x2F);
57 assert!(c2 >= 0x20 && c2 <= 0x2F);
58 Self { data: [c1, c2] }
59 }
60
61 pub fn has(&self, c: u8) -> bool {
62 self.data[0] == c || self.data[1] == c
63 }
64
65 pub fn clear(&mut self) {
66 self.data[0] = 0;
67 self.data[1] = 0;
68 }
69
70 pub fn is_empty(&self) -> bool {
71 self.data[0] == 0 && self.data[1] == 0
72 }
73
74 pub fn len(&self) -> usize {
75 self.data.iter().filter(|&&c| c != 0).count()
76 }
77
78 pub fn first(&self) -> Option<u8> {
79 if self.data[0] != 0 {
80 Some(self.data[0])
81 } else {
82 None
83 }
84 }
85
86 pub fn second(&self) -> Option<u8> {
87 if self.data[1] != 0 {
88 Some(self.data[1])
89 } else {
90 None
91 }
92 }
93
94 #[must_use]
95 pub fn push(&mut self, c: u8) -> bool {
96 if !(0x20..=0x2F).contains(&c) {
97 return false;
98 }
99
100 if self.data[0] == c {
102 return false;
103 }
104
105 if self.data[0] == 0 {
106 self.data[0] = c;
107 true
108 } else if self.data[1] == 0 {
109 self.data[1] = c;
110 true
111 } else {
112 false
113 }
114 }
115
116 pub const fn const_eq(&self, other: &Self) -> bool {
117 self.data[0] == other.data[0] && self.data[1] == other.data[1]
118 }
119
120 pub fn byte_len(&self) -> usize {
121 self.data.iter().filter(|&&c| c != 0).count()
122 }
123}
124
125impl AsRef<[u8]> for VTIntermediate {
126 fn as_ref(&self) -> &[u8] {
127 &self.data[..self.byte_len()]
128 }
129}
130
131impl std::fmt::Debug for VTIntermediate {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 write!(f, "'")?;
135 for c in self.data.iter() {
136 if *c == 0 {
137 break;
138 }
139 write!(f, "{}", *c as char)?;
140 }
141 write!(f, "'")?;
142 Ok(())
143 }
144}
145
146pub(crate) type Param = SmallVec<[u8; 32]>;
147pub(crate) type Params = SmallVec<[Param; 8]>;
148
149static EMPTY_PARAMS: Params = Params::new_const();
150
151#[cfg_attr(feature = "serde", derive(serde::Serialize))]
152#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
153#[repr(transparent)]
154pub struct ParamBuf<'a> {
155 pub(crate) params: &'a Params,
156}
157
158impl<'a> IntoIterator for ParamBuf<'a> {
159 type Item = &'a [u8];
160 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
161 fn into_iter(self) -> Self::IntoIter {
162 self.params.iter().map(|p| p.as_slice())
163 }
164}
165
166impl<'a> IntoIterator for &ParamBuf<'a> {
167 type Item = &'a [u8];
168 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
169 fn into_iter(self) -> Self::IntoIter {
170 self.params.iter().map(|p| p.as_slice())
171 }
172}
173
174impl<'a> ParamBuf<'a> {
175 pub const fn empty() -> Self {
176 ParamBuf {
177 params: &EMPTY_PARAMS,
178 }
179 }
180
181 pub fn len(&self) -> usize {
182 self.params.len()
183 }
184
185 pub fn is_empty(&self) -> bool {
186 self.params.is_empty()
187 }
188
189 pub fn get(&self, index: usize) -> Option<&[u8]> {
190 self.params.get(index).map(|p| p.as_slice())
191 }
192
193 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
194 self.params.get(index).and_then(|p| {
195 std::str::from_utf8(p.as_slice())
196 .ok()
197 .and_then(|s| s.parse::<T>().ok())
198 })
199 }
200
201 pub fn to_owned(&self) -> ParamBufOwned {
202 ParamBufOwned {
203 params: self.params.iter().cloned().collect(),
204 }
205 }
206
207 pub fn byte_len(&self) -> usize {
208 self.params.iter().map(|p| p.len()).sum::<usize>() + self.params.len().saturating_sub(1)
209 }
210
211 pub fn numeric(&self) -> NumericParamBuf<'a> {
212 NumericParamBuf {
213 params: self.params,
214 }
215 }
216}
217
218#[derive(Debug, Copy, Clone, Default)]
220pub struct NumericParam<'a> {
221 pub(crate) param: &'a [u8],
222}
223
224impl<'a> NumericParam<'a> {
225 pub fn sole(&self) -> Option<u16> {
227 if !self.param.is_empty() && !self.param.contains(&b':') {
228 if let Ok(s) = std::str::from_utf8(self.param) {
229 s.parse::<u16>().ok()
230 } else {
231 None
232 }
233 } else {
234 None
235 }
236 }
237
238 pub fn first(&self) -> Option<u16> {
240 self.into_iter().next().flatten()
241 }
242
243 pub fn is_empty(&self) -> bool {
244 self.param.is_empty()
245 }
246
247 pub fn len(&self) -> usize {
248 self.param.iter().filter(|p| **p == b':').count() + 1
249 }
250
251 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
258 let len = self.len();
259 if buf.len() < len {
260 return Err(buf.len());
261 }
262 for (i, param) in self.into_iter().enumerate() {
263 buf[i] = param.unwrap_or(0);
264 }
265 Ok(&buf[..len])
266 }
267}
268
269impl<'a> IntoIterator for NumericParam<'a> {
270 type Item = Option<u16>;
271 type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
272 fn into_iter(self) -> Self::IntoIter {
273 let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
274 self.param.split(fn1).map(|p| {
275 if p.is_empty() {
276 None
277 } else {
278 std::str::from_utf8(p)
279 .ok()
280 .and_then(|s| s.parse::<u16>().ok())
281 }
282 })
283 }
284}
285
286#[derive(Debug, Copy, Clone)]
291pub struct NumericParamBuf<'a> {
292 pub(crate) params: &'a Params,
293}
294
295impl<'a> IntoIterator for NumericParamBuf<'a> {
296 type Item = NumericParam<'a>;
297 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&'a Param) -> NumericParam<'a>>;
298 fn into_iter(self) -> Self::IntoIter {
299 self.params.iter().map(|p| NumericParam {
300 param: p.as_slice(),
301 })
302 }
303}
304
305impl<'a> NumericParamBuf<'a> {
306 pub const fn empty() -> Self {
307 NumericParamBuf {
308 params: &EMPTY_PARAMS,
309 }
310 }
311
312 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
319 let len = self.params.len();
320 if buf.len() < len {
321 return Err(buf.len());
322 }
323 for (i, param) in self.into_iter().enumerate() {
324 buf[i] = param.sole().unwrap_or(0);
325 }
326 Ok(&buf[..len])
327 }
328
329 pub fn get(&self, index: usize) -> Option<NumericParam<'a>> {
330 self.params.get(index).map(|p| NumericParam {
331 param: p.as_slice(),
332 })
333 }
334
335 pub fn first(&self) -> Option<NumericParam<'a>> {
336 self.into_iter().next()
337 }
338
339 pub fn is_empty(&self) -> bool {
340 self.params.is_empty()
341 }
342
343 pub fn len(&self) -> usize {
344 self.params.len()
345 }
346}
347
348#[cfg_attr(feature = "serde", derive(serde::Serialize))]
351#[derive(Clone, PartialEq, Eq, Hash)]
352pub enum VTEvent<'a> {
353 Raw(&'a [u8]),
355
356 C0(u8),
358
359 Esc(Esc),
361
362 EscInvalid(EscInvalid),
364
365 Ss2(SS2),
367
368 Ss3(SS3),
370
371 Csi(CSI<'a>),
373
374 DcsStart(DCS<'a>),
376 DcsData(&'a [u8]),
377 DcsEnd(&'a [u8]),
378 DcsCancel,
379
380 OscStart,
382 OscData(&'a [u8]),
383 OscEnd {
384 data: &'a [u8],
385 used_bel: bool,
387 },
388 OscCancel,
389}
390
391impl<'a> std::fmt::Debug for VTEvent<'a> {
392 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393 use VTEvent::*;
394 match self {
395 Raw(s) => {
396 write!(f, "Raw('")?;
397 fmt_utf8_bytes_with_ascii_control(f, s)?;
398 write!(f, "')")?;
399 Ok(())
400 }
401 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
402 C0(b) => write!(f, "C0({b:02x})"),
403 Esc(esc) => esc.fmt(f),
404 Ss2(ss2) => ss2.fmt(f),
405 Ss3(ss3) => ss3.fmt(f),
406 Csi(csi) => csi.fmt(f),
407 DcsStart(dcs_start) => dcs_start.fmt(f),
408 DcsData(s) | DcsEnd(s) => {
409 if matches!(self, DcsEnd(..)) {
410 write!(f, "DcsEnd('")?;
411 } else {
412 write!(f, "DcsData('")?;
413 }
414 fmt_utf8_bytes_with_ascii_control(f, s)?;
415 write!(f, "')")?;
416 Ok(())
417 }
418 DcsCancel => write!(f, "DcsCancel"),
419 OscStart => write!(f, "OscStart"),
420 OscData(s) | OscEnd { data: s, .. } => {
421 if matches!(self, OscEnd { .. }) {
422 write!(f, "OscEnd('")?;
423 } else {
424 write!(f, "OscData('")?;
425 }
426 fmt_utf8_bytes_with_ascii_control(f, s)?;
427 write!(f, "')")?;
428 Ok(())
429 }
430 OscCancel => write!(f, "OscCancel"),
431 }
432 }
433}
434
435impl<'a> VTEvent<'a> {
436 pub fn csi(&self) -> Option<CSI<'a>> {
437 match self {
438 VTEvent::Csi(csi) => Some(CSI {
439 private: csi.private,
440 params: csi.params,
441 intermediates: csi.intermediates,
442 final_byte: csi.final_byte,
443 }),
444 _ => None,
445 }
446 }
447
448 pub fn byte_len(&self) -> usize {
449 use VTEvent::*;
450
451 match self {
452 Raw(s) => s.len(),
453 C0(_) => 1,
454 Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
455 EscInvalid(esc_invalid) => {
456 use self::EscInvalid::*;
457 match esc_invalid {
458 One(..) => 2,
459 Two(..) => 3,
460 Three(..) => 4,
461 Four(..) => 5,
462 }
463 }
464 Ss2(_) => 3,
465 Ss3(_) => 3,
466 Csi(csi) => {
467 csi.private.is_some() as usize
468 + csi.params.byte_len()
469 + csi.intermediates.byte_len()
470 + 3
471 }
472 DcsStart(dcs_start) => {
473 dcs_start.private.is_some() as usize
474 + dcs_start.params.byte_len()
475 + dcs_start.intermediates.byte_len()
476 + 3
477 }
478 DcsData(s) => s.len(),
479 DcsEnd(s) => s.len() + 2,
480 DcsCancel => 1,
481 OscStart => 2,
482 OscData(s) => s.len(),
483 OscEnd { data, used_bel } => {
484 if *used_bel {
485 data.len() + 1
486 } else {
487 data.len() + 2
488 }
489 }
490 OscCancel => 1,
491 }
492 }
493
494 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
500 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
501 use VTEvent::*;
502
503 let len = self.byte_len();
504
505 if len > buf.len() {
506 return Err(len);
507 }
508
509 match self {
510 Raw(s) | OscData(s) | DcsData(s) => {
511 buf[..s.len()].copy_from_slice(s);
512 }
513 EscInvalid(esc_invalid) => {
514 use self::EscInvalid::*;
515 buf[0] = ESC;
516 match esc_invalid {
517 One(b) => buf[1] = *b,
518 Two(b1, b2) => {
519 buf[1] = *b1;
520 buf[2] = *b2;
521 }
522 Three(b1, b2, b3) => {
523 buf[1] = *b1;
524 buf[2] = *b2;
525 buf[3] = *b3;
526 }
527 Four(b1, b2, b3, b4) => {
528 buf[1] = *b1;
529 buf[2] = *b2;
530 buf[3] = *b3;
531 buf[4] = *b4;
532 }
533 }
534 }
535 OscCancel | DcsCancel => {
536 buf[0] = CAN;
537 }
538 C0(b) => {
539 buf[0] = *b;
540 }
541 Ss2(ss2) => {
542 buf[0] = ESC;
543 buf[1] = SS2;
544 buf[2] = ss2.char;
545 }
546 Ss3(ss3) => {
547 buf[0] = ESC;
548 buf[1] = SS3;
549 buf[2] = ss3.char;
550 }
551 Esc(esc) => {
552 buf[0] = ESC;
553 if let Some(p) = esc.private {
554 buf[1] = p;
555 buf = &mut buf[1..];
556 }
557 buf[1..esc.intermediates.len() + 1]
558 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
559 buf[esc.intermediates.len() + 1] = esc.final_byte;
560 }
561 Csi(csi) => {
562 buf[0] = ESC;
563 buf[1] = CSI;
564 buf = &mut buf[2..];
565 if let Some(p) = csi.private {
566 buf[0] = p;
567 buf = &mut buf[1..];
568 }
569 let mut params = csi.params.into_iter();
570 if let Some(param) = params.next() {
571 buf[..param.len()].copy_from_slice(param);
572 buf = &mut buf[param.len()..];
573 for param in params {
574 buf[0] = b';';
575 buf = &mut buf[1..];
576 buf[..param.len()].copy_from_slice(param);
577 buf = &mut buf[param.len()..];
578 }
579 }
580 buf[..csi.intermediates.len()]
581 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
582 buf[csi.intermediates.len()] = csi.final_byte;
583 }
584 DcsStart(dcs_start) => {
585 buf[0] = ESC;
586 buf[1] = DCS;
587 buf = &mut buf[2..];
588 if let Some(p) = dcs_start.private {
589 buf[0] = p;
590 buf = &mut buf[1..];
591 }
592 let mut params = dcs_start.params.into_iter();
593 if let Some(param) = params.next() {
594 buf[..param.len()].copy_from_slice(param);
595 buf = &mut buf[param.len()..];
596 for param in params {
597 buf[0] = b';';
598 buf = &mut buf[1..];
599 buf[..param.len()].copy_from_slice(param);
600 buf = &mut buf[param.len()..];
601 }
602 }
603 buf[..dcs_start.intermediates.len()].copy_from_slice(
604 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
605 );
606 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
607 }
608 DcsEnd(data) => {
609 buf[..data.len()].copy_from_slice(data);
610 buf = &mut buf[data.len()..];
611 buf[0] = ESC;
612 buf[1] = ST_FINAL;
613 }
614 OscStart => {
615 buf[0] = ESC;
616 buf[1] = OSC;
617 }
618 OscEnd { data, used_bel } => {
619 buf[..data.len()].copy_from_slice(data);
620 buf = &mut buf[data.len()..];
621 if *used_bel {
622 buf[0] = BEL;
623 } else {
624 buf[0] = ESC;
625 buf[1] = ST_FINAL
626 }
627 }
628 }
629
630 Ok(len)
631 }
632
633 pub fn write_to(&self, mut writer: impl io::Write) -> Result<usize, io::Error> {
642 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
643
644 use VTEvent::*;
645 let mut len = 0;
646 match self {
647 Raw(s) | OscData(s) | DcsData(s) => {
648 writer.write_all(s)?;
649 len = s.len();
650 }
651 EscInvalid(esc_invalid) => {
652 use self::EscInvalid::*;
653 match esc_invalid {
654 One(b) => {
655 writer.write_all(&[ESC, *b])?;
656 len = 2;
657 }
658 Two(b1, b2) => {
659 writer.write_all(&[ESC, *b1, *b2])?;
660 len = 3;
661 }
662 Three(b1, b2, b3) => {
663 writer.write_all(&[ESC, *b1, *b2, *b3])?;
664 len = 4;
665 }
666 Four(b1, b2, b3, b4) => {
667 writer.write_all(&[ESC, *b1, *b2, *b3, *b4])?;
668 len = 5;
669 }
670 }
671 }
672 OscCancel | DcsCancel => {
673 writer.write_all(&[CAN])?;
674 len = 1;
675 }
676 C0(b) => {
677 writer.write_all(&[*b])?;
678 len = 1;
679 }
680 Ss2(ss2) => {
681 writer.write_all(&[ESC, SS2, ss2.char])?;
682 len = 3;
683 }
684 Ss3(ss3) => {
685 writer.write_all(&[ESC, SS3, ss3.char])?;
686 len = 3;
687 }
688 Esc(esc) => {
689 writer.write_all(&[ESC])?;
690 len = 1;
691 if let Some(p) = esc.private {
692 writer.write_all(&[p])?;
693 len = 2;
694 }
695 if !esc.intermediates.is_empty() {
696 writer.write_all(&esc.intermediates.data[..esc.intermediates.len()])?;
697 len += esc.intermediates.len();
698 }
699 writer.write_all(&[esc.final_byte])?;
700 len += 1;
701 }
702 Csi(csi) => {
703 writer.write_all(&[ESC, CSI])?;
704 len = 2;
705 if let Some(p) = csi.private {
706 writer.write_all(&[p])?;
707 len = 3;
708 }
709 let mut first = true;
710 for param in csi.params {
711 if !first {
712 writer.write_all(b";")?;
713 len += 1;
714 } else {
715 first = false;
716 }
717 writer.write_all(param)?;
718 len += param.len();
719 }
720 if !csi.intermediates.is_empty() {
721 writer.write_all(&csi.intermediates.data[..csi.intermediates.len()])?;
722 len += csi.intermediates.len();
723 }
724 writer.write_all(&[csi.final_byte])?;
725 len += 1;
726 }
727 DcsStart(dcs_start) => {
728 writer.write_all(&[ESC, DCS])?;
729 len = 2;
730 if let Some(p) = dcs_start.private {
731 writer.write_all(&[p])?;
732 len = 3;
733 }
734 let mut first = true;
735 for param in dcs_start.params {
736 if !first {
737 writer.write_all(b";")?;
738 len += 1;
739 } else {
740 first = false;
741 }
742 writer.write_all(param)?;
743 len += param.len();
744 }
745 if !dcs_start.intermediates.is_empty() {
746 writer.write_all(
747 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
748 )?;
749 len += dcs_start.intermediates.len();
750 }
751 writer.write_all(&[dcs_start.final_byte])?;
752 len += 1;
753 }
754 DcsEnd(s) => {
755 writer.write_all(s)?;
756 len += s.len();
757 writer.write_all(&[ESC, ST_FINAL])?;
758 len += 2;
759 }
760 OscStart => {
761 writer.write_all(&[ESC, OSC])?;
762 len = 2;
763 }
764 OscEnd { data, used_bel } => {
765 writer.write_all(data)?;
766 if *used_bel {
767 writer.write_all(&[BEL])?;
768 len = 1 + data.len();
769 } else {
770 writer.write_all(&[ESC, ST_FINAL])?;
771 len = 2 + data.len();
772 }
773 }
774 }
775 Ok(len)
776 }
777
778 pub fn to_owned(&self) -> VTOwnedEvent {
779 use VTEvent::*;
780 match self {
781 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
782 C0(b) => VTOwnedEvent::C0(*b),
783 Esc(esc) => VTOwnedEvent::Esc(*esc),
784 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
785 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
786 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
787 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
788 private: csi.private,
789 params: csi.params.to_owned(),
790 intermediates: csi.intermediates,
791 final_byte: csi.final_byte,
792 }),
793 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
794 private: dcs_start.private,
795 params: dcs_start.params.to_owned(),
796 intermediates: dcs_start.intermediates,
797 final_byte: dcs_start.final_byte,
798 }),
799 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
800 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
801 DcsCancel => VTOwnedEvent::DcsCancel,
802 OscStart => VTOwnedEvent::OscStart,
803 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
804 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
805 data: data.to_vec(),
806 used_bel: *used_bel,
807 },
808 OscCancel => VTOwnedEvent::OscCancel,
809 }
810 }
811}
812
813#[cfg_attr(feature = "serde", derive(serde::Serialize))]
814#[derive(Clone, PartialEq, Eq, Debug, Default)]
815pub struct ParamBufOwned {
816 pub(crate) params: Params,
817}
818
819impl IntoIterator for ParamBufOwned {
820 type Item = Param;
821 type IntoIter = <Params as IntoIterator>::IntoIter;
822 fn into_iter(self) -> Self::IntoIter {
823 self.params.into_iter()
824 }
825}
826
827impl<'b> IntoIterator for &'b ParamBufOwned {
828 type Item = &'b [u8];
829 type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
830 fn into_iter(self) -> Self::IntoIter {
831 self.params.iter().map(|p| p.as_slice())
832 }
833}
834
835impl ParamBufOwned {
836 pub const fn empty() -> Self {
838 Self {
839 params: SmallVec::new_const(),
840 }
841 }
842
843 pub fn new(params: &[&[u8]]) -> Self {
845 Self {
846 params: params.iter().map(|p| Param::from(*p)).collect(),
847 }
848 }
849
850 pub fn len(&self) -> usize {
851 self.params.len()
852 }
853
854 pub fn is_empty(&self) -> bool {
855 self.params.is_empty()
856 }
857
858 pub fn get(&self, index: usize) -> Option<&[u8]> {
859 self.params.get(index).map(|p| p.as_slice())
860 }
861
862 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
863 self.params.get(index).and_then(|p| {
864 std::str::from_utf8(p.as_slice())
865 .ok()
866 .and_then(|s| s.parse::<T>().ok())
867 })
868 }
869
870 pub fn borrow(&self) -> ParamBuf<'_> {
871 ParamBuf {
872 params: &self.params,
873 }
874 }
875
876 pub fn numeric(&self) -> NumericParamBuf<'_> {
877 NumericParamBuf {
878 params: &self.params,
879 }
880 }
881}
882
883#[cfg_attr(feature = "serde", derive(serde::Serialize))]
886#[derive(Clone, PartialEq, Eq)]
887pub enum VTOwnedEvent {
888 Raw(Vec<u8>),
889 C0(u8),
890 Esc(Esc),
891 EscInvalid(EscInvalid),
892 Ss2(SS2),
893 Ss3(SS3),
894 Csi(CSIOwned),
895 DcsStart(DCSOwned),
896 DcsData(Vec<u8>),
897 DcsEnd(Vec<u8>),
898 DcsCancel,
899 OscStart,
900 OscData(Vec<u8>),
901 OscEnd { data: Vec<u8>, used_bel: bool },
902 OscCancel,
903}
904
905impl std::fmt::Debug for VTOwnedEvent {
906 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
907 self.borrow().fmt(f)
908 }
909}
910
911impl VTOwnedEvent {
912 pub fn borrow(&self) -> VTEvent<'_> {
913 match self {
914 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
915 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
916 VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
917 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
918 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
919 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
920 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
921 private: csi.private,
922 params: csi.params.borrow(),
923 intermediates: csi.intermediates,
924 final_byte: csi.final_byte,
925 }),
926 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
927 private: dcs_start.private,
928 params: dcs_start.params.borrow(),
929 intermediates: dcs_start.intermediates,
930 final_byte: dcs_start.final_byte,
931 }),
932 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
933 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
934 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
935 VTOwnedEvent::OscStart => VTEvent::OscStart,
936 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
937 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
938 data,
939 used_bel: *used_bel,
940 },
941 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
942 }
943 }
944}
945
946#[cfg_attr(feature = "serde", derive(serde::Serialize))]
948#[derive(Clone, Copy, PartialEq, Eq, Hash)]
949pub enum EscInvalid {
950 One(u8),
951 Two(u8, u8),
952 Three(u8, u8, u8),
953 Four(u8, u8, u8, u8),
954}
955
956impl std::fmt::Debug for EscInvalid {
957 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
958 match self {
959 EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
960 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
961 EscInvalid::Three(b1, b2, b3) => {
962 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
963 }
964 EscInvalid::Four(b1, b2, b3, b4) => {
965 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
966 }
967 }
968 Ok(())
969 }
970}
971
972#[cfg_attr(feature = "serde", derive(serde::Serialize))]
973#[derive(Clone, Copy, PartialEq, Eq, Hash)]
974pub struct Esc {
975 pub intermediates: VTIntermediate,
976 pub private: Option<u8>,
977 pub final_byte: u8,
978}
979
980impl std::fmt::Debug for Esc {
981 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
982 write!(f, "Esc(")?;
983 if let Some(p) = self.private {
984 write!(f, "{:?}, ", p as char)?;
985 }
986 write!(f, "{:?}, ", self.intermediates)?;
987 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
988 write!(f, "{c})")?;
989 } else {
990 write!(f, "{})", self.final_byte as char)?;
991 }
992 Ok(())
993 }
994}
995
996#[cfg_attr(feature = "serde", derive(serde::Serialize))]
997#[derive(Clone, Copy, PartialEq, Eq, Hash)]
998pub struct SS2 {
999 pub char: u8,
1000}
1001
1002impl std::fmt::Debug for SS2 {
1003 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1004 write!(f, "Ss2(")?;
1005 if let Ok(c) = AsciiControl::try_from(self.char as char) {
1006 write!(f, "{c})")?;
1007 } else {
1008 write!(f, "{:?})", self.char as char)?;
1009 }
1010 Ok(())
1011 }
1012}
1013
1014#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1015#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1016pub struct SS3 {
1017 pub char: u8,
1018}
1019
1020impl std::fmt::Debug for SS3 {
1021 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1022 write!(f, "Ss3(")?;
1023 if let Ok(c) = AsciiControl::try_from(self.char as char) {
1024 write!(f, "{c})")?;
1025 } else {
1026 write!(f, "{:?})", self.char as char)?;
1027 }
1028 Ok(())
1029 }
1030}
1031
1032#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1033#[derive(Clone, PartialEq, Eq, Hash)]
1034pub struct CSI<'a> {
1035 pub private: Option<u8>,
1036 pub params: ParamBuf<'a>,
1037 pub intermediates: VTIntermediate,
1038 pub final_byte: u8,
1039}
1040
1041impl<'a> std::fmt::Debug for CSI<'a> {
1042 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1043 write!(f, "Csi(")?;
1044 if let Some(p) = self.private {
1045 write!(f, "{:?}, ", p as char)?;
1046 }
1047 for param in &self.params {
1048 write!(f, "'")?;
1049 fmt_utf8_bytes_simple(f, param)?;
1050 write!(f, "', ")?;
1051 }
1052 write!(f, "{:?}, ", self.intermediates)?;
1053 write!(f, "{:?})", self.final_byte as char)?;
1054 Ok(())
1055 }
1056}
1057
1058#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1059#[derive(Clone, PartialEq, Eq, Hash)]
1060pub struct DCS<'a> {
1061 pub private: Option<u8>,
1062 pub params: ParamBuf<'a>,
1063 pub intermediates: VTIntermediate,
1064 pub final_byte: u8,
1065}
1066
1067impl<'a> std::fmt::Debug for DCS<'a> {
1068 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1069 write!(f, "DcsStart(")?;
1070 if let Some(p) = self.private {
1071 write!(f, "{:?}, ", p as char)?;
1072 }
1073 for param in &self.params {
1074 write!(f, "'")?;
1075 fmt_utf8_bytes_simple(f, param)?;
1076 write!(f, "', ")?;
1077 }
1078 write!(f, "{:?}, ", self.intermediates)?;
1079 write!(f, "{})", self.final_byte as char)?;
1080 Ok(())
1081 }
1082}
1083
1084#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1085#[derive(Clone, PartialEq, Eq)]
1086pub struct CSIOwned {
1087 pub private: Option<u8>,
1088 pub params: ParamBufOwned,
1089 pub intermediates: VTIntermediate,
1090 pub final_byte: u8,
1091}
1092
1093impl std::fmt::Debug for CSIOwned {
1094 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1095 write!(f, "Csi(")?;
1096 if let Some(p) = self.private {
1097 write!(f, "{:?}", p as char)?;
1098 }
1099 for param in &self.params {
1100 write!(f, ", '")?;
1101 fmt_utf8_bytes_simple(f, param)?;
1102 write!(f, "'")?;
1103 }
1104 write!(f, ", {:?}", self.intermediates)?;
1105 write!(f, ", {:?})", self.final_byte as char)?;
1106 Ok(())
1107 }
1108}
1109
1110#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1111#[derive(Clone, PartialEq, Eq)]
1112pub struct DCSOwned {
1113 pub private: Option<u8>,
1114 pub params: ParamBufOwned,
1115 pub intermediates: VTIntermediate,
1116 pub final_byte: u8,
1117}
1118
1119impl std::fmt::Debug for DCSOwned {
1120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1121 write!(f, "DcsStart(")?;
1122 if let Some(p) = self.private {
1123 write!(f, "{:?}", p as char)?;
1124 }
1125 for param in &self.params {
1126 write!(f, ", '")?;
1127 fmt_utf8_bytes_simple(f, param)?;
1128 write!(f, "'")?;
1129 }
1130 write!(f, ", {:?}", self.intermediates)?;
1131 write!(f, ", {})", self.final_byte as char)?;
1132 Ok(())
1133 }
1134}
1135
1136#[cfg(test)]
1137mod test {
1138 use super::*;
1139
1140 #[test]
1141 fn test_numeric_param_buf() {
1142 let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
1143 let numeric_param_buf = param_buf.numeric();
1144 assert_eq!(
1145 numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
1146 vec![Some(1), Some(2), Some(3), Some(4), None, None]
1147 );
1148
1149 assert_eq!(numeric_param_buf.first().unwrap().sole(), None);
1150 assert_eq!(numeric_param_buf.first().unwrap().first(), Some(1));
1151 assert_eq!(numeric_param_buf.get(1).unwrap().sole(), Some(4));
1152 assert_eq!(numeric_param_buf.get(1).unwrap().first(), Some(4));
1153 assert_eq!(numeric_param_buf.get(2).unwrap().sole(), None);
1154 assert_eq!(numeric_param_buf.get(2).unwrap().first(), None);
1155
1156 assert_eq!(
1157 numeric_param_buf
1158 .try_write(&mut [0, 0, 0, 0, 0, 0])
1159 .unwrap(),
1160 &[0, 4, 0]
1161 );
1162 assert_eq!(
1163 numeric_param_buf
1164 .get(0)
1165 .unwrap()
1166 .try_write(&mut [0, 0, 0, 0, 0, 0])
1167 .unwrap(),
1168 &[1, 2, 3]
1169 );
1170 }
1171}