1use std::{io, iter::Map};
3
4use crate::AsciiControl;
5
6fn fmt_utf8_bytes_with_ascii_control(
8 f: &mut std::fmt::Formatter<'_>,
9 bytes: &[u8],
10) -> std::fmt::Result {
11 for chunk in bytes.utf8_chunks() {
12 for c in chunk.valid().chars() {
13 if let Ok(c) = AsciiControl::try_from(c) {
14 write!(f, "{c}")?;
15 } else {
16 write!(f, "{c}")?;
17 }
18 }
19 if !chunk.invalid().is_empty() {
20 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
21 }
22 }
23 Ok(())
24}
25
26fn fmt_utf8_bytes_simple(f: &mut std::fmt::Formatter<'_>, bytes: &[u8]) -> std::fmt::Result {
28 for chunk in bytes.utf8_chunks() {
29 write!(f, "{}", chunk.valid())?;
30 if !chunk.invalid().is_empty() {
31 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
32 }
33 }
34 Ok(())
35}
36
37#[cfg_attr(feature = "serde", derive(serde::Serialize))]
38#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
39pub struct VTIntermediate {
40 pub(crate) data: [u8; 2],
41}
42
43impl VTIntermediate {
44 pub const fn empty() -> Self {
45 Self { data: [0, 0] }
46 }
47
48 pub const fn one(c: u8) -> Self {
49 assert!(c >= 0x20 && c <= 0x2F);
50 Self { data: [c, 0] }
51 }
52
53 pub const fn two(c1: u8, c2: u8) -> Self {
54 assert!(c1 >= 0x20 && c1 <= 0x2F);
55 assert!(c2 >= 0x20 && c2 <= 0x2F);
56 Self { data: [c1, c2] }
57 }
58
59 pub fn has(&self, c: u8) -> bool {
60 self.data[0] == c || self.data[1] == c
61 }
62
63 pub fn clear(&mut self) {
64 self.data[0] = 0;
65 self.data[1] = 0;
66 }
67
68 pub fn is_empty(&self) -> bool {
69 self.data[0] == 0 && self.data[1] == 0
70 }
71
72 pub fn len(&self) -> usize {
73 self.data.iter().filter(|&&c| c != 0).count()
74 }
75
76 pub fn first(&self) -> Option<u8> {
77 if self.data[0] != 0 {
78 Some(self.data[0])
79 } else {
80 None
81 }
82 }
83
84 pub fn second(&self) -> Option<u8> {
85 if self.data[1] != 0 {
86 Some(self.data[1])
87 } else {
88 None
89 }
90 }
91
92 #[must_use]
93 pub fn push(&mut self, c: u8) -> bool {
94 if !(0x20..=0x2F).contains(&c) {
95 return false;
96 }
97
98 if self.data[0] == c {
100 return false;
101 }
102
103 if self.data[0] == 0 {
104 self.data[0] = c;
105 true
106 } else if self.data[1] == 0 {
107 self.data[1] = c;
108 true
109 } else {
110 false
111 }
112 }
113
114 pub const fn const_eq(&self, other: &Self) -> bool {
115 self.data[0] == other.data[0] && self.data[1] == other.data[1]
116 }
117
118 pub fn byte_len(&self) -> usize {
119 self.data.iter().filter(|&&c| c != 0).count()
120 }
121}
122
123impl AsRef<[u8]> for VTIntermediate {
124 fn as_ref(&self) -> &[u8] {
125 &self.data[..self.byte_len()]
126 }
127}
128
129impl std::fmt::Debug for VTIntermediate {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 write!(f, "'")?;
133 for c in self.data.iter() {
134 if *c == 0 {
135 break;
136 }
137 write!(f, "{}", *c as char)?;
138 }
139 write!(f, "'")?;
140 Ok(())
141 }
142}
143
144#[derive(Clone, Copy)]
148pub struct Param {
149 data: [u8; MAX_PARAM_LEN],
150 len: u8,
151 overflowed: bool,
153}
154
155impl Param {
156 pub const EMPTY: Self = Self {
158 data: [0; MAX_PARAM_LEN],
159 len: 0,
160 overflowed: false,
161 };
162
163 #[inline]
166 pub fn overflowed(&self) -> bool {
167 self.overflowed
168 }
169
170 #[inline]
172 pub fn push(&mut self, b: u8) {
173 if (self.len as usize) < MAX_PARAM_LEN {
174 self.data[self.len as usize] = b;
175 self.len += 1;
176 } else {
177 self.overflowed = true;
178 }
179 }
180
181 #[inline]
183 pub fn extend_from_slice(&mut self, bytes: &[u8]) {
184 for &b in bytes {
185 self.push(b);
186 }
187 }
188
189 #[inline]
191 pub fn clear(&mut self) {
192 self.len = 0;
193 self.overflowed = false;
194 }
195
196 #[inline]
198 pub fn as_slice(&self) -> &[u8] {
199 &self.data[..self.len as usize]
200 }
201}
202
203impl std::ops::Deref for Param {
204 type Target = [u8];
205
206 #[inline]
207 fn deref(&self) -> &[u8] {
208 self.as_slice()
209 }
210}
211
212impl AsRef<[u8]> for Param {
213 #[inline]
214 fn as_ref(&self) -> &[u8] {
215 self.as_slice()
216 }
217}
218
219impl PartialEq for Param {
220 fn eq(&self, other: &Self) -> bool {
221 self.as_slice() == other.as_slice()
222 }
223}
224
225impl Eq for Param {}
226
227impl std::hash::Hash for Param {
228 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
229 self.as_slice().hash(state)
230 }
231}
232
233impl std::fmt::Debug for Param {
234 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235 f.debug_list().entries(self.as_slice()).finish()
236 }
237}
238
239pub const MAX_PARAMS: usize = 128;
241
242pub const MAX_PARAM_LEN: usize = 32;
245
246pub const MAX_PARAM_BYTES: usize = 1024;
249
250#[derive(Clone, Copy)]
261pub struct ParamList {
262 lens: [u8; MAX_PARAMS],
264 data: [u8; MAX_PARAM_BYTES],
266 count: u16,
268 used: u16,
270 overflowed: bool,
272}
273
274impl ParamList {
275 pub const EMPTY: Self = Self {
277 lens: [0; MAX_PARAMS],
278 data: [0; MAX_PARAM_BYTES],
279 count: 0,
280 used: 0,
281 overflowed: false,
282 };
283
284 #[inline]
286 pub fn len(&self) -> usize {
287 self.count as usize
288 }
289
290 #[inline]
292 pub fn is_empty(&self) -> bool {
293 self.count == 0
294 }
295
296 #[inline]
298 pub fn iter(&self) -> ParamListIter<'_> {
299 let (data, lens, count) = ParamSource::Inline(self).parts();
300 ParamListIter {
301 data,
302 lens,
303 count,
304 index: 0,
305 offset: 0,
306 }
307 }
308
309 #[inline]
313 pub fn overflowed(&self) -> bool {
314 self.overflowed
315 }
316
317 #[inline]
320 pub(crate) fn mark_overflowed(&mut self) {
321 self.overflowed = true;
322 }
323
324 #[inline]
326 pub fn get(&self, index: usize) -> Option<&[u8]> {
327 if index >= self.count as usize {
328 return None;
329 }
330 let offset: usize = self.lens[..index].iter().map(|&len| len as usize).sum();
331 let len = self.lens[index] as usize;
332 Some(&self.data[offset..offset + len])
333 }
334
335 #[inline]
337 pub fn byte_len(&self) -> usize {
338 self.used as usize + self.count.saturating_sub(1) as usize
339 }
340
341 #[inline]
348 pub fn push_param(&mut self, param: &[u8]) {
349 if param.len() > MAX_PARAM_LEN {
350 self.overflowed = true;
351 }
352 if self.count as usize >= MAX_PARAMS || self.used as usize >= MAX_PARAM_BYTES {
353 self.overflowed = true;
354 return;
355 }
356 let remaining = MAX_PARAM_BYTES - self.used as usize;
357 let len = param.len().min(MAX_PARAM_LEN).min(remaining);
358 if len < param.len() {
359 self.overflowed = true;
360 }
361 let start = self.used as usize;
362 self.data[start..start + len].copy_from_slice(¶m[..len]);
363 self.lens[self.count as usize] = len as u8;
364 self.count += 1;
365 self.used += len as u16;
366 }
367
368 #[inline]
370 pub fn clear(&mut self) {
371 self.count = 0;
372 self.used = 0;
373 self.overflowed = false;
374 }
375}
376
377impl PartialEq for ParamList {
378 fn eq(&self, other: &Self) -> bool {
379 self.count == other.count && self.iter().eq(other.iter())
382 }
383}
384
385impl Eq for ParamList {}
386
387impl std::hash::Hash for ParamList {
388 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
389 self.count.hash(state);
392 for param in self.iter() {
393 param.hash(state);
394 }
395 }
396}
397
398impl Default for ParamList {
399 fn default() -> Self {
400 Self::EMPTY
401 }
402}
403
404impl std::fmt::Debug for ParamList {
405 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
406 f.debug_list().entries(self.iter()).finish()
407 }
408}
409
410#[cfg(feature = "serde")]
411impl serde::Serialize for ParamList {
412 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
413 use serde::ser::SerializeSeq;
414 let mut seq = serializer.serialize_seq(Some(self.count as usize))?;
415 for param in self.iter() {
416 seq.serialize_element(param)?;
417 }
418 seq.end()
419 }
420}
421
422static EMPTY_PARAMS: ParamList = ParamList::EMPTY;
423
424#[derive(Copy, Clone)]
427pub(crate) enum ParamSource<'a> {
428 Inline(&'a ParamList),
429 Owned(&'a ParamBufOwned),
430}
431
432impl<'a> ParamSource<'a> {
433 #[inline]
436 fn parts(self) -> (&'a [u8], &'a [u8], usize) {
437 match self {
438 ParamSource::Inline(list) => (
439 &list.data[..list.used as usize],
440 &list.lens[..list.count as usize],
441 list.count as usize,
442 ),
443 ParamSource::Owned(owned) => (
444 owned.data.as_deref().unwrap_or(&[]),
445 owned.lens.as_deref().unwrap_or(&[]),
446 owned.lens.as_ref().map_or(0, |lens| lens.len()),
447 ),
448 }
449 }
450
451 #[inline]
452 fn len(self) -> usize {
453 self.parts().2
454 }
455
456 #[inline]
457 fn is_empty(self) -> bool {
458 self.len() == 0
459 }
460
461 #[inline]
462 fn overflowed(self) -> bool {
463 match self {
464 ParamSource::Inline(list) => list.overflowed(),
465 ParamSource::Owned(owned) => owned.overflowed,
466 }
467 }
468
469 fn get(self, index: usize) -> Option<&'a [u8]> {
470 let (data, lens, count) = self.parts();
471 if index >= count {
472 return None;
473 }
474 let offset: usize = lens[..index].iter().map(|&len| len as usize).sum();
475 let len = lens[index] as usize;
476 Some(&data[offset..offset + len])
477 }
478
479 #[inline]
480 fn byte_len(self) -> usize {
481 let (data, _, count) = self.parts();
482 data.len() + count.saturating_sub(1)
483 }
484
485 #[inline]
486 fn iter(self) -> ParamListIter<'a> {
487 let (data, lens, count) = self.parts();
488 ParamListIter {
489 data,
490 lens,
491 count,
492 index: 0,
493 offset: 0,
494 }
495 }
496}
497
498impl PartialEq for ParamSource<'_> {
499 fn eq(&self, other: &Self) -> bool {
500 self.iter().eq(other.iter())
501 }
502}
503
504impl Eq for ParamSource<'_> {}
505
506impl std::hash::Hash for ParamSource<'_> {
507 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
508 self.len().hash(state);
510 for param in self.iter() {
511 param.hash(state);
512 }
513 }
514}
515
516impl std::fmt::Debug for ParamSource<'_> {
517 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
518 f.debug_list().entries(self.iter()).finish()
519 }
520}
521
522#[cfg(feature = "serde")]
523impl serde::Serialize for ParamSource<'_> {
524 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
525 use serde::ser::SerializeSeq;
526 let mut seq = serializer.serialize_seq(Some(self.len()))?;
527 for param in self.iter() {
528 seq.serialize_element(param)?;
529 }
530 seq.end()
531 }
532}
533
534#[cfg_attr(feature = "serde", derive(serde::Serialize))]
548#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
549#[repr(transparent)]
550pub struct ParamBuf<'a> {
551 pub(crate) params: ParamSource<'a>,
552}
553
554impl<'a> IntoIterator for ParamBuf<'a> {
555 type Item = &'a [u8];
556 type IntoIter = std::iter::Map<ParamListIter<'a>, fn(&'a [u8]) -> &'a [u8]>;
557 fn into_iter(self) -> Self::IntoIter {
558 self.params.iter().map(|p| p as &[u8])
559 }
560}
561
562impl<'a> IntoIterator for &ParamBuf<'a> {
563 type Item = &'a [u8];
564 type IntoIter = std::iter::Map<ParamListIter<'a>, fn(&'a [u8]) -> &'a [u8]>;
565 fn into_iter(self) -> Self::IntoIter {
566 self.params.iter().map(|p| p as &[u8])
567 }
568}
569
570impl<'a> ParamBuf<'a> {
571 pub const fn empty() -> Self {
572 ParamBuf {
573 params: ParamSource::Inline(&EMPTY_PARAMS),
574 }
575 }
576
577 pub(crate) const fn from_param_list(list: &'a ParamList) -> Self {
579 ParamBuf {
580 params: ParamSource::Inline(list),
581 }
582 }
583
584 pub fn len(&self) -> usize {
585 self.params.len()
586 }
587
588 pub fn is_empty(&self) -> bool {
589 self.params.is_empty()
590 }
591
592 pub fn get(&self, index: usize) -> Option<&[u8]> {
593 self.params.get(index)
594 }
595
596 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
597 self.params.get(index).and_then(|p| {
598 std::str::from_utf8(p)
599 .ok()
600 .and_then(|s| s.parse::<T>().ok())
601 })
602 }
603
604 pub fn to_owned(&self) -> ParamBufOwned {
605 match self.params {
606 ParamSource::Inline(list) => ParamBufOwned::from_param_list(list),
607 ParamSource::Owned(owned) => owned.clone(),
608 }
609 }
610
611 pub fn overflowed(&self) -> bool {
614 self.params.overflowed()
615 }
616
617 pub fn byte_len(&self) -> usize {
618 self.params.byte_len()
619 }
620
621 pub fn numeric(&self) -> NumericParamBuf<'a> {
622 NumericParamBuf {
623 params: self.params,
624 }
625 }
626}
627
628pub struct ParamListIter<'a> {
635 data: &'a [u8],
637 lens: &'a [u8],
639 count: usize,
641 index: usize,
642 offset: usize,
643}
644
645impl<'a> Iterator for ParamListIter<'a> {
646 type Item = &'a [u8];
647
648 #[inline]
649 fn next(&mut self) -> Option<Self::Item> {
650 if self.index >= self.count {
651 return None;
652 }
653 let len = self.lens[self.index] as usize;
654 let param = &self.data[self.offset..self.offset + len];
655 self.index += 1;
656 self.offset += len;
657 Some(param)
658 }
659
660 #[inline]
661 fn size_hint(&self) -> (usize, Option<usize>) {
662 let remaining = self.count - self.index;
663 (remaining, Some(remaining))
664 }
665}
666
667impl ExactSizeIterator for ParamListIter<'_> {}
668
669impl std::iter::FusedIterator for ParamListIter<'_> {}
670
671#[derive(Debug, Copy, Clone, Default)]
673pub struct NumericParam<'a> {
674 pub(crate) param: &'a [u8],
675}
676
677impl<'a> NumericParam<'a> {
678 pub fn sole(&self) -> Option<u16> {
680 if !self.param.is_empty() && !self.param.contains(&b':') {
681 if let Ok(s) = std::str::from_utf8(self.param) {
682 s.parse::<u16>().ok()
683 } else {
684 None
685 }
686 } else {
687 None
688 }
689 }
690
691 pub fn first(&self) -> Option<u16> {
693 self.into_iter().next().flatten()
694 }
695
696 pub fn is_empty(&self) -> bool {
697 self.param.is_empty()
698 }
699
700 pub fn len(&self) -> usize {
701 self.param.iter().filter(|p| **p == b':').count() + 1
702 }
703
704 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
711 let len = self.len();
712 if buf.len() < len {
713 return Err(buf.len());
714 }
715 for (i, param) in self.into_iter().enumerate() {
716 buf[i] = param.unwrap_or(0);
717 }
718 Ok(&buf[..len])
719 }
720}
721
722impl<'a> IntoIterator for NumericParam<'a> {
723 type Item = Option<u16>;
724 type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
725 fn into_iter(self) -> Self::IntoIter {
726 let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
727 self.param.split(fn1).map(|p| {
728 if p.is_empty() {
729 None
730 } else {
731 std::str::from_utf8(p)
732 .ok()
733 .and_then(|s| s.parse::<u16>().ok())
734 }
735 })
736 }
737}
738
739#[derive(Debug, Copy, Clone)]
744pub struct NumericParamBuf<'a> {
745 pub(crate) params: ParamSource<'a>,
746}
747
748impl<'a> IntoIterator for NumericParamBuf<'a> {
749 type Item = NumericParam<'a>;
750 type IntoIter = std::iter::Map<ParamListIter<'a>, fn(&'a [u8]) -> NumericParam<'a>>;
751 fn into_iter(self) -> Self::IntoIter {
752 self.params.iter().map(|p| NumericParam { param: p })
753 }
754}
755
756impl<'a> NumericParamBuf<'a> {
757 pub const fn empty() -> Self {
758 NumericParamBuf {
759 params: ParamSource::Inline(&EMPTY_PARAMS),
760 }
761 }
762
763 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
770 let len = self.params.len();
771 if buf.len() < len {
772 return Err(buf.len());
773 }
774 for (i, param) in self.into_iter().enumerate() {
775 buf[i] = param.sole().unwrap_or(0);
776 }
777 Ok(&buf[..len])
778 }
779
780 pub fn get(&self, index: usize) -> Option<NumericParam<'a>> {
781 self.params.get(index).map(|p| NumericParam { param: p })
782 }
783
784 pub fn first(&self) -> Option<NumericParam<'a>> {
785 self.into_iter().next()
786 }
787
788 pub fn is_empty(&self) -> bool {
789 self.params.is_empty()
790 }
791
792 pub fn len(&self) -> usize {
793 self.params.len()
794 }
795}
796
797#[cfg_attr(feature = "serde", derive(serde::Serialize))]
800#[derive(Clone, PartialEq, Eq, Hash)]
801pub enum VTEvent<'a> {
802 Raw(&'a [u8]),
804
805 C0(u8),
807
808 Esc(Esc),
810
811 EscInvalid(EscInvalid),
813
814 Ss2(SS2),
816
817 Ss3(SS3),
819
820 Csi(CSI<'a>),
822
823 DcsStart(DCS<'a>),
825 DcsData(&'a [u8]),
826 DcsEnd(&'a [u8]),
827 DcsCancel,
828
829 OscStart,
831 OscData(&'a [u8]),
832 OscEnd {
833 data: &'a [u8],
834 used_bel: bool,
836 },
837 OscCancel,
838}
839
840impl<'a> std::fmt::Debug for VTEvent<'a> {
841 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
842 use VTEvent::*;
843 match self {
844 Raw(s) => {
845 write!(f, "Raw('")?;
846 fmt_utf8_bytes_with_ascii_control(f, s)?;
847 write!(f, "')")?;
848 Ok(())
849 }
850 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
851 C0(b) => write!(f, "C0({b:02x})"),
852 Esc(esc) => esc.fmt(f),
853 Ss2(ss2) => ss2.fmt(f),
854 Ss3(ss3) => ss3.fmt(f),
855 Csi(csi) => csi.fmt(f),
856 DcsStart(dcs_start) => dcs_start.fmt(f),
857 DcsData(s) | DcsEnd(s) => {
858 if matches!(self, DcsEnd(..)) {
859 write!(f, "DcsEnd('")?;
860 } else {
861 write!(f, "DcsData('")?;
862 }
863 fmt_utf8_bytes_with_ascii_control(f, s)?;
864 write!(f, "')")?;
865 Ok(())
866 }
867 DcsCancel => write!(f, "DcsCancel"),
868 OscStart => write!(f, "OscStart"),
869 OscData(s) | OscEnd { data: s, .. } => {
870 if matches!(self, OscEnd { .. }) {
871 write!(f, "OscEnd('")?;
872 } else {
873 write!(f, "OscData('")?;
874 }
875 fmt_utf8_bytes_with_ascii_control(f, s)?;
876 write!(f, "')")?;
877 Ok(())
878 }
879 OscCancel => write!(f, "OscCancel"),
880 }
881 }
882}
883
884impl<'a> VTEvent<'a> {
885 pub fn csi(&self) -> Option<CSI<'a>> {
886 match self {
887 VTEvent::Csi(csi) => Some(CSI {
888 private: csi.private,
889 params: csi.params,
890 intermediates: csi.intermediates,
891 final_byte: csi.final_byte,
892 }),
893 _ => None,
894 }
895 }
896
897 pub fn byte_len(&self) -> usize {
898 use VTEvent::*;
899
900 match self {
901 Raw(s) => s.len(),
902 C0(_) => 1,
903 Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
904 EscInvalid(esc_invalid) => {
905 use self::EscInvalid::*;
906 match esc_invalid {
907 One(..) => 2,
908 Two(..) => 3,
909 Three(..) => 4,
910 Four(..) => 5,
911 }
912 }
913 Ss2(_) => 3,
914 Ss3(_) => 3,
915 Csi(csi) => {
916 csi.private.is_some() as usize
917 + csi.params.byte_len()
918 + csi.intermediates.byte_len()
919 + 3
920 }
921 DcsStart(dcs_start) => {
922 dcs_start.private.is_some() as usize
923 + dcs_start.params.byte_len()
924 + dcs_start.intermediates.byte_len()
925 + 3
926 }
927 DcsData(s) => s.len(),
928 DcsEnd(s) => s.len() + 2,
929 DcsCancel => 1,
930 OscStart => 2,
931 OscData(s) => s.len(),
932 OscEnd { data, used_bel } => {
933 if *used_bel {
934 data.len() + 1
935 } else {
936 data.len() + 2
937 }
938 }
939 OscCancel => 1,
940 }
941 }
942
943 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
949 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
950 use VTEvent::*;
951
952 let len = self.byte_len();
953
954 if len > buf.len() {
955 return Err(len);
956 }
957
958 match self {
959 Raw(s) | OscData(s) | DcsData(s) => {
960 buf[..s.len()].copy_from_slice(s);
961 }
962 EscInvalid(esc_invalid) => {
963 use self::EscInvalid::*;
964 buf[0] = ESC;
965 match esc_invalid {
966 One(b) => buf[1] = *b,
967 Two(b1, b2) => {
968 buf[1] = *b1;
969 buf[2] = *b2;
970 }
971 Three(b1, b2, b3) => {
972 buf[1] = *b1;
973 buf[2] = *b2;
974 buf[3] = *b3;
975 }
976 Four(b1, b2, b3, b4) => {
977 buf[1] = *b1;
978 buf[2] = *b2;
979 buf[3] = *b3;
980 buf[4] = *b4;
981 }
982 }
983 }
984 OscCancel | DcsCancel => {
985 buf[0] = CAN;
986 }
987 C0(b) => {
988 buf[0] = *b;
989 }
990 Ss2(ss2) => {
991 buf[0] = ESC;
992 buf[1] = SS2;
993 buf[2] = ss2.char;
994 }
995 Ss3(ss3) => {
996 buf[0] = ESC;
997 buf[1] = SS3;
998 buf[2] = ss3.char;
999 }
1000 Esc(esc) => {
1001 buf[0] = ESC;
1002 if let Some(p) = esc.private {
1003 buf[1] = p;
1004 buf = &mut buf[1..];
1005 }
1006 buf[1..esc.intermediates.len() + 1]
1007 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
1008 buf[esc.intermediates.len() + 1] = esc.final_byte;
1009 }
1010 Csi(csi) => {
1011 buf[0] = ESC;
1012 buf[1] = CSI;
1013 buf = &mut buf[2..];
1014 if let Some(p) = csi.private {
1015 buf[0] = p;
1016 buf = &mut buf[1..];
1017 }
1018 let mut params = csi.params.into_iter();
1019 if let Some(param) = params.next() {
1020 buf[..param.len()].copy_from_slice(param);
1021 buf = &mut buf[param.len()..];
1022 for param in params {
1023 buf[0] = b';';
1024 buf = &mut buf[1..];
1025 buf[..param.len()].copy_from_slice(param);
1026 buf = &mut buf[param.len()..];
1027 }
1028 }
1029 buf[..csi.intermediates.len()]
1030 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
1031 buf[csi.intermediates.len()] = csi.final_byte;
1032 }
1033 DcsStart(dcs_start) => {
1034 buf[0] = ESC;
1035 buf[1] = DCS;
1036 buf = &mut buf[2..];
1037 if let Some(p) = dcs_start.private {
1038 buf[0] = p;
1039 buf = &mut buf[1..];
1040 }
1041 let mut params = dcs_start.params.into_iter();
1042 if let Some(param) = params.next() {
1043 buf[..param.len()].copy_from_slice(param);
1044 buf = &mut buf[param.len()..];
1045 for param in params {
1046 buf[0] = b';';
1047 buf = &mut buf[1..];
1048 buf[..param.len()].copy_from_slice(param);
1049 buf = &mut buf[param.len()..];
1050 }
1051 }
1052 buf[..dcs_start.intermediates.len()].copy_from_slice(
1053 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
1054 );
1055 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
1056 }
1057 DcsEnd(data) => {
1058 buf[..data.len()].copy_from_slice(data);
1059 buf = &mut buf[data.len()..];
1060 buf[0] = ESC;
1061 buf[1] = ST_FINAL;
1062 }
1063 OscStart => {
1064 buf[0] = ESC;
1065 buf[1] = OSC;
1066 }
1067 OscEnd { data, used_bel } => {
1068 buf[..data.len()].copy_from_slice(data);
1069 buf = &mut buf[data.len()..];
1070 if *used_bel {
1071 buf[0] = BEL;
1072 } else {
1073 buf[0] = ESC;
1074 buf[1] = ST_FINAL
1075 }
1076 }
1077 }
1078
1079 Ok(len)
1080 }
1081
1082 pub fn write_to(&self, mut writer: impl io::Write) -> Result<usize, io::Error> {
1091 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
1092
1093 use VTEvent::*;
1094 let mut len = 0;
1095 match self {
1096 Raw(s) | OscData(s) | DcsData(s) => {
1097 writer.write_all(s)?;
1098 len = s.len();
1099 }
1100 EscInvalid(esc_invalid) => {
1101 use self::EscInvalid::*;
1102 match esc_invalid {
1103 One(b) => {
1104 writer.write_all(&[ESC, *b])?;
1105 len = 2;
1106 }
1107 Two(b1, b2) => {
1108 writer.write_all(&[ESC, *b1, *b2])?;
1109 len = 3;
1110 }
1111 Three(b1, b2, b3) => {
1112 writer.write_all(&[ESC, *b1, *b2, *b3])?;
1113 len = 4;
1114 }
1115 Four(b1, b2, b3, b4) => {
1116 writer.write_all(&[ESC, *b1, *b2, *b3, *b4])?;
1117 len = 5;
1118 }
1119 }
1120 }
1121 OscCancel | DcsCancel => {
1122 writer.write_all(&[CAN])?;
1123 len = 1;
1124 }
1125 C0(b) => {
1126 writer.write_all(&[*b])?;
1127 len = 1;
1128 }
1129 Ss2(ss2) => {
1130 writer.write_all(&[ESC, SS2, ss2.char])?;
1131 len = 3;
1132 }
1133 Ss3(ss3) => {
1134 writer.write_all(&[ESC, SS3, ss3.char])?;
1135 len = 3;
1136 }
1137 Esc(esc) => {
1138 writer.write_all(&[ESC])?;
1139 len = 1;
1140 if let Some(p) = esc.private {
1141 writer.write_all(&[p])?;
1142 len = 2;
1143 }
1144 if !esc.intermediates.is_empty() {
1145 writer.write_all(&esc.intermediates.data[..esc.intermediates.len()])?;
1146 len += esc.intermediates.len();
1147 }
1148 writer.write_all(&[esc.final_byte])?;
1149 len += 1;
1150 }
1151 Csi(csi) => {
1152 writer.write_all(&[ESC, CSI])?;
1153 len = 2;
1154 if let Some(p) = csi.private {
1155 writer.write_all(&[p])?;
1156 len = 3;
1157 }
1158 let mut first = true;
1159 for param in csi.params {
1160 if !first {
1161 writer.write_all(b";")?;
1162 len += 1;
1163 } else {
1164 first = false;
1165 }
1166 writer.write_all(param)?;
1167 len += param.len();
1168 }
1169 if !csi.intermediates.is_empty() {
1170 writer.write_all(&csi.intermediates.data[..csi.intermediates.len()])?;
1171 len += csi.intermediates.len();
1172 }
1173 writer.write_all(&[csi.final_byte])?;
1174 len += 1;
1175 }
1176 DcsStart(dcs_start) => {
1177 writer.write_all(&[ESC, DCS])?;
1178 len = 2;
1179 if let Some(p) = dcs_start.private {
1180 writer.write_all(&[p])?;
1181 len = 3;
1182 }
1183 let mut first = true;
1184 for param in dcs_start.params {
1185 if !first {
1186 writer.write_all(b";")?;
1187 len += 1;
1188 } else {
1189 first = false;
1190 }
1191 writer.write_all(param)?;
1192 len += param.len();
1193 }
1194 if !dcs_start.intermediates.is_empty() {
1195 writer.write_all(
1196 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
1197 )?;
1198 len += dcs_start.intermediates.len();
1199 }
1200 writer.write_all(&[dcs_start.final_byte])?;
1201 len += 1;
1202 }
1203 DcsEnd(s) => {
1204 writer.write_all(s)?;
1205 len += s.len();
1206 writer.write_all(&[ESC, ST_FINAL])?;
1207 len += 2;
1208 }
1209 OscStart => {
1210 writer.write_all(&[ESC, OSC])?;
1211 len = 2;
1212 }
1213 OscEnd { data, used_bel } => {
1214 writer.write_all(data)?;
1215 if *used_bel {
1216 writer.write_all(&[BEL])?;
1217 len = 1 + data.len();
1218 } else {
1219 writer.write_all(&[ESC, ST_FINAL])?;
1220 len = 2 + data.len();
1221 }
1222 }
1223 }
1224 Ok(len)
1225 }
1226
1227 pub fn to_owned(&self) -> VTOwnedEvent {
1228 use VTEvent::*;
1229 match self {
1230 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
1231 C0(b) => VTOwnedEvent::C0(*b),
1232 Esc(esc) => VTOwnedEvent::Esc(*esc),
1233 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
1234 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
1235 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
1236 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
1237 private: csi.private,
1238 params: csi.params.to_owned(),
1239 intermediates: csi.intermediates,
1240 final_byte: csi.final_byte,
1241 }),
1242 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
1243 private: dcs_start.private,
1244 params: dcs_start.params.to_owned(),
1245 intermediates: dcs_start.intermediates,
1246 final_byte: dcs_start.final_byte,
1247 }),
1248 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
1249 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
1250 DcsCancel => VTOwnedEvent::DcsCancel,
1251 OscStart => VTOwnedEvent::OscStart,
1252 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
1253 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
1254 data: data.to_vec(),
1255 used_bel: *used_bel,
1256 },
1257 OscCancel => VTOwnedEvent::OscCancel,
1258 }
1259 }
1260}
1261
1262#[derive(Clone, PartialEq, Eq, Debug, Default)]
1273pub struct ParamBufOwned {
1274 pub(crate) data: Option<Box<[u8]>>,
1275 pub(crate) lens: Option<Box<[u8]>>,
1276 pub(crate) overflowed: bool,
1277}
1278
1279#[cfg(feature = "serde")]
1280impl serde::Serialize for ParamBufOwned {
1281 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1282 use serde::ser::SerializeMap;
1283 let mut map = serializer.serialize_map(Some(1))?;
1284 map.serialize_entry("params", &ParamSource::Owned(self))?;
1285 map.end()
1286 }
1287}
1288
1289impl ParamBufOwned {
1290 pub(crate) fn from_param_list(list: &ParamList) -> Self {
1292 if list.count == 0 {
1293 return Self::EMPTY;
1294 }
1295 let data = &list.data[..list.used as usize];
1296 let lens = &list.lens[..list.count as usize];
1297 Self {
1298 data: Some(data.to_vec().into_boxed_slice()),
1299 lens: Some(lens.to_vec().into_boxed_slice()),
1300 overflowed: list.overflowed,
1301 }
1302 }
1303
1304 pub const EMPTY: Self = Self {
1306 data: None,
1307 lens: None,
1308 overflowed: false,
1309 };
1310
1311 pub const fn empty() -> Self {
1313 Self::EMPTY
1314 }
1315
1316 pub fn new(params: &[&[u8]]) -> Self {
1321 let mut list = ParamList::EMPTY;
1322 for param in params {
1323 list.push_param(param);
1324 }
1325 Self::from_param_list(&list)
1326 }
1327
1328 pub fn len(&self) -> usize {
1329 self.lens.as_ref().map_or(0, |lens| lens.len())
1330 }
1331
1332 pub fn is_empty(&self) -> bool {
1333 self.len() == 0
1334 }
1335
1336 pub fn get(&self, index: usize) -> Option<&[u8]> {
1337 ParamSource::Owned(self).get(index)
1338 }
1339
1340 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
1341 self.get(index).and_then(|p| {
1342 std::str::from_utf8(p)
1343 .ok()
1344 .and_then(|s| s.parse::<T>().ok())
1345 })
1346 }
1347
1348 pub fn overflowed(&self) -> bool {
1351 self.overflowed
1352 }
1353
1354 pub fn byte_len(&self) -> usize {
1356 ParamSource::Owned(self).byte_len()
1357 }
1358
1359 pub fn borrow(&self) -> ParamBuf<'_> {
1360 ParamBuf {
1361 params: ParamSource::Owned(self),
1362 }
1363 }
1364
1365 pub fn numeric(&self) -> NumericParamBuf<'_> {
1366 NumericParamBuf {
1367 params: ParamSource::Owned(self),
1368 }
1369 }
1370}
1371
1372pub struct ParamBufOwnedIter {
1374 data: Box<[u8]>,
1375 lens: Box<[u8]>,
1376 index: usize,
1377 offset: usize,
1378}
1379
1380impl Iterator for ParamBufOwnedIter {
1381 type Item = Param;
1382
1383 #[inline]
1384 fn next(&mut self) -> Option<Self::Item> {
1385 if self.index >= self.lens.len() {
1386 return None;
1387 }
1388 let len = self.lens[self.index] as usize;
1389 let mut param = Param::EMPTY;
1390 param.extend_from_slice(&self.data[self.offset..self.offset + len]);
1391 self.index += 1;
1392 self.offset += len;
1393 Some(param)
1394 }
1395
1396 #[inline]
1397 fn size_hint(&self) -> (usize, Option<usize>) {
1398 let remaining = self.lens.len() - self.index;
1399 (remaining, Some(remaining))
1400 }
1401}
1402
1403impl ExactSizeIterator for ParamBufOwnedIter {}
1404
1405impl std::iter::FusedIterator for ParamBufOwnedIter {}
1406
1407impl IntoIterator for ParamBufOwned {
1408 type Item = Param;
1409 type IntoIter = ParamBufOwnedIter;
1410 fn into_iter(self) -> Self::IntoIter {
1411 ParamBufOwnedIter {
1412 data: self.data.unwrap_or_default(),
1413 lens: self.lens.unwrap_or_default(),
1414 index: 0,
1415 offset: 0,
1416 }
1417 }
1418}
1419
1420impl<'b> IntoIterator for &'b ParamBufOwned {
1421 type Item = &'b [u8];
1422 type IntoIter = ParamListIter<'b>;
1423 fn into_iter(self) -> Self::IntoIter {
1424 ParamSource::Owned(self).iter()
1425 }
1426}
1427
1428#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1431#[derive(Clone, PartialEq, Eq)]
1432pub enum VTOwnedEvent {
1433 Raw(Vec<u8>),
1434 C0(u8),
1435 Esc(Esc),
1436 EscInvalid(EscInvalid),
1437 Ss2(SS2),
1438 Ss3(SS3),
1439 Csi(CSIOwned),
1440 DcsStart(DCSOwned),
1441 DcsData(Vec<u8>),
1442 DcsEnd(Vec<u8>),
1443 DcsCancel,
1444 OscStart,
1445 OscData(Vec<u8>),
1446 OscEnd { data: Vec<u8>, used_bel: bool },
1447 OscCancel,
1448}
1449
1450impl std::fmt::Debug for VTOwnedEvent {
1451 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1452 self.borrow().fmt(f)
1453 }
1454}
1455
1456impl VTOwnedEvent {
1457 pub fn borrow(&self) -> VTEvent<'_> {
1458 match self {
1459 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
1460 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
1461 VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
1462 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
1463 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
1464 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
1465 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
1466 private: csi.private,
1467 params: csi.params.borrow(),
1468 intermediates: csi.intermediates,
1469 final_byte: csi.final_byte,
1470 }),
1471 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
1472 private: dcs_start.private,
1473 params: dcs_start.params.borrow(),
1474 intermediates: dcs_start.intermediates,
1475 final_byte: dcs_start.final_byte,
1476 }),
1477 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
1478 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
1479 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
1480 VTOwnedEvent::OscStart => VTEvent::OscStart,
1481 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
1482 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
1483 data,
1484 used_bel: *used_bel,
1485 },
1486 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
1487 }
1488 }
1489}
1490
1491#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1493#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1494pub enum EscInvalid {
1495 One(u8),
1496 Two(u8, u8),
1497 Three(u8, u8, u8),
1498 Four(u8, u8, u8, u8),
1499}
1500
1501impl std::fmt::Debug for EscInvalid {
1502 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1503 match self {
1504 EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
1505 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
1506 EscInvalid::Three(b1, b2, b3) => {
1507 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
1508 }
1509 EscInvalid::Four(b1, b2, b3, b4) => {
1510 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
1511 }
1512 }
1513 Ok(())
1514 }
1515}
1516
1517#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1518#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1519pub struct Esc {
1520 pub intermediates: VTIntermediate,
1521 pub private: Option<u8>,
1522 pub final_byte: u8,
1523}
1524
1525impl std::fmt::Debug for Esc {
1526 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1527 write!(f, "Esc(")?;
1528 if let Some(p) = self.private {
1529 write!(f, "{:?}, ", p as char)?;
1530 }
1531 write!(f, "{:?}, ", self.intermediates)?;
1532 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
1533 write!(f, "{c})")?;
1534 } else {
1535 write!(f, "{})", self.final_byte as char)?;
1536 }
1537 Ok(())
1538 }
1539}
1540
1541#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1542#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1543pub struct SS2 {
1544 pub char: u8,
1545}
1546
1547impl std::fmt::Debug for SS2 {
1548 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1549 write!(f, "Ss2(")?;
1550 if let Ok(c) = AsciiControl::try_from(self.char as char) {
1551 write!(f, "{c})")?;
1552 } else {
1553 write!(f, "{:?})", self.char as char)?;
1554 }
1555 Ok(())
1556 }
1557}
1558
1559#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1560#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1561pub struct SS3 {
1562 pub char: u8,
1563}
1564
1565impl std::fmt::Debug for SS3 {
1566 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1567 write!(f, "Ss3(")?;
1568 if let Ok(c) = AsciiControl::try_from(self.char as char) {
1569 write!(f, "{c})")?;
1570 } else {
1571 write!(f, "{:?})", self.char as char)?;
1572 }
1573 Ok(())
1574 }
1575}
1576
1577#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1578#[derive(Clone, PartialEq, Eq, Hash)]
1579pub struct CSI<'a> {
1580 pub private: Option<u8>,
1581 pub params: ParamBuf<'a>,
1582 pub intermediates: VTIntermediate,
1583 pub final_byte: u8,
1584}
1585
1586impl<'a> std::fmt::Debug for CSI<'a> {
1587 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1588 write!(f, "Csi(")?;
1589 if let Some(p) = self.private {
1590 write!(f, "{:?}, ", p as char)?;
1591 }
1592 for param in &self.params {
1593 write!(f, "'")?;
1594 fmt_utf8_bytes_simple(f, param)?;
1595 write!(f, "', ")?;
1596 }
1597 write!(f, "{:?}, ", self.intermediates)?;
1598 write!(f, "{:?})", self.final_byte as char)?;
1599 Ok(())
1600 }
1601}
1602
1603#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1604#[derive(Clone, PartialEq, Eq, Hash)]
1605pub struct DCS<'a> {
1606 pub private: Option<u8>,
1607 pub params: ParamBuf<'a>,
1608 pub intermediates: VTIntermediate,
1609 pub final_byte: u8,
1610}
1611
1612impl<'a> std::fmt::Debug for DCS<'a> {
1613 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1614 write!(f, "DcsStart(")?;
1615 if let Some(p) = self.private {
1616 write!(f, "{:?}, ", p as char)?;
1617 }
1618 for param in &self.params {
1619 write!(f, "'")?;
1620 fmt_utf8_bytes_simple(f, param)?;
1621 write!(f, "', ")?;
1622 }
1623 write!(f, "{:?}, ", self.intermediates)?;
1624 write!(f, "{})", self.final_byte as char)?;
1625 Ok(())
1626 }
1627}
1628
1629#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1630#[derive(Clone, PartialEq, Eq)]
1631pub struct CSIOwned {
1632 pub private: Option<u8>,
1633 pub params: ParamBufOwned,
1634 pub intermediates: VTIntermediate,
1635 pub final_byte: u8,
1636}
1637
1638impl std::fmt::Debug for CSIOwned {
1639 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1640 write!(f, "Csi(")?;
1641 if let Some(p) = self.private {
1642 write!(f, "{:?}", p as char)?;
1643 }
1644 for param in &self.params {
1645 write!(f, ", '")?;
1646 fmt_utf8_bytes_simple(f, param)?;
1647 write!(f, "'")?;
1648 }
1649 write!(f, ", {:?}", self.intermediates)?;
1650 write!(f, ", {:?})", self.final_byte as char)?;
1651 Ok(())
1652 }
1653}
1654
1655#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1656#[derive(Clone, PartialEq, Eq)]
1657pub struct DCSOwned {
1658 pub private: Option<u8>,
1659 pub params: ParamBufOwned,
1660 pub intermediates: VTIntermediate,
1661 pub final_byte: u8,
1662}
1663
1664impl std::fmt::Debug for DCSOwned {
1665 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1666 write!(f, "DcsStart(")?;
1667 if let Some(p) = self.private {
1668 write!(f, "{:?}", p as char)?;
1669 }
1670 for param in &self.params {
1671 write!(f, ", '")?;
1672 fmt_utf8_bytes_simple(f, param)?;
1673 write!(f, "'")?;
1674 }
1675 write!(f, ", {:?}", self.intermediates)?;
1676 write!(f, ", {})", self.final_byte as char)?;
1677 Ok(())
1678 }
1679}
1680
1681#[cfg(test)]
1682mod test {
1683 use super::*;
1684
1685 #[test]
1686 fn test_numeric_param_buf() {
1687 let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
1688 let numeric_param_buf = param_buf.numeric();
1689 assert_eq!(
1690 numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
1691 vec![Some(1), Some(2), Some(3), Some(4), None, None]
1692 );
1693
1694 assert_eq!(numeric_param_buf.first().unwrap().sole(), None);
1695 assert_eq!(numeric_param_buf.first().unwrap().first(), Some(1));
1696 assert_eq!(numeric_param_buf.get(1).unwrap().sole(), Some(4));
1697 assert_eq!(numeric_param_buf.get(1).unwrap().first(), Some(4));
1698 assert_eq!(numeric_param_buf.get(2).unwrap().sole(), None);
1699 assert_eq!(numeric_param_buf.get(2).unwrap().first(), None);
1700
1701 assert_eq!(
1702 numeric_param_buf
1703 .try_write(&mut [0, 0, 0, 0, 0, 0])
1704 .unwrap(),
1705 &[0, 4, 0]
1706 );
1707 assert_eq!(
1708 numeric_param_buf
1709 .get(0)
1710 .unwrap()
1711 .try_write(&mut [0, 0, 0, 0, 0, 0])
1712 .unwrap(),
1713 &[1, 2, 3]
1714 );
1715 }
1716
1717 #[test]
1718 fn param_buf_owned_is_content_sized() {
1719 let empty = ParamBufOwned::new(&[]);
1721 assert!(empty.data.is_none());
1722 assert!(empty.lens.is_none());
1723 assert!(empty.is_empty());
1724 assert_eq!(empty.len(), 0);
1725
1726 let small = ParamBufOwned::new(&[b"1234", b"5"]);
1730 assert_eq!(small.data.as_deref(), Some(&b"12345"[..]));
1731 assert_eq!(small.lens.as_deref(), Some(&[4, 1][..]));
1732 assert_eq!(small.len(), 2);
1733 assert_eq!(small.byte_len(), 6); assert!(!small.overflowed());
1735
1736 let strings: Vec<String> = (0..MAX_PARAMS as u32).map(|i| i.to_string()).collect();
1738 let slices: Vec<&[u8]> = strings.iter().map(|s| s.as_bytes()).collect();
1739 let many = ParamBufOwned::new(&slices);
1740 assert_eq!(many.len(), MAX_PARAMS);
1741 assert_eq!(many.get(0), Some(&b"0"[..]));
1742 assert_eq!(many.get(127), Some(&b"127"[..]));
1743 assert_eq!(many.byte_len(), 10 + 90 * 2 + 28 * 3 + 127);
1744 }
1745
1746 #[test]
1747 fn param_buf_owned_clamps_like_param_buf() {
1748 let long = ParamBufOwned::new(&[&[b'7'; MAX_PARAM_LEN + 8][..]]);
1752 assert_eq!(long.len(), 1);
1753 assert_eq!(long.get(0).map(<[u8]>::len), Some(MAX_PARAM_LEN));
1754 assert!(long.overflowed());
1755
1756 let too_many_strings: Vec<String> = (0..(MAX_PARAMS + 8) as u32)
1757 .map(|i| i.to_string())
1758 .collect();
1759 let too_many_slices: Vec<&[u8]> = too_many_strings.iter().map(|s| s.as_bytes()).collect();
1760 let too_many = ParamBufOwned::new(&too_many_slices);
1761 assert_eq!(too_many.len(), MAX_PARAMS);
1762 assert!(too_many.overflowed());
1763
1764 assert!(ParamBuf::empty().to_owned().is_empty());
1766 assert_eq!(ParamBuf::empty().to_owned(), ParamBufOwned::empty());
1767 }
1768
1769 #[test]
1770 fn param_buf_owned_views_match_parser_views() {
1771 let owned = ParamBufOwned::new(&[b"1", b"22", b""]);
1774
1775 let mut list = ParamList::EMPTY;
1776 list.push_param(b"1");
1777 list.push_param(b"22");
1778 list.push_param(b"");
1779 let view = ParamBuf::from_param_list(&list);
1780
1781 assert_eq!(owned.borrow(), view);
1782 assert_eq!(owned.borrow().len(), view.len());
1783 assert_eq!(owned.borrow().byte_len(), view.byte_len());
1784 assert_eq!(
1785 owned.numeric().try_write(&mut [0; 4]).unwrap(),
1786 view.numeric().try_write(&mut [0; 4]).unwrap()
1787 );
1788 assert_eq!(
1789 owned.borrow().into_iter().collect::<Vec<_>>(),
1790 view.into_iter().collect::<Vec<_>>()
1791 );
1792 assert_eq!(
1793 (&owned).into_iter().collect::<Vec<_>>(),
1794 view.into_iter().collect::<Vec<_>>()
1795 );
1796 assert_eq!(format!("{:?}", owned.borrow()), format!("{:?}", view));
1797
1798 let copy = owned.borrow().to_owned();
1800 assert_eq!(copy, owned);
1801 assert_eq!(copy.get(1), Some(&b"22"[..]));
1802
1803 fn param(bytes: &[u8]) -> Param {
1805 let mut p = Param::EMPTY;
1806 p.extend_from_slice(bytes);
1807 p
1808 }
1809 assert_eq!(
1810 owned.into_iter().collect::<Vec<_>>(),
1811 vec![param(b"1"), param(b"22"), Param::EMPTY]
1812 );
1813 }
1814
1815 #[test]
1816 fn param_buf_owned_overflowed_from_parser() {
1817 let mut list = ParamList::EMPTY;
1819 list.push_param(&[b'7'; MAX_PARAM_LEN + 8]);
1820 list.push_param(b"1");
1821 let owned = ParamBuf::from_param_list(&list).to_owned();
1822 assert!(owned.overflowed());
1823 assert_eq!(owned.len(), 2);
1824 assert_eq!(owned.get(0).map(<[u8]>::len), Some(MAX_PARAM_LEN));
1825
1826 let mut list = ParamList::EMPTY;
1828 list.push_param(b"1");
1829 let owned = ParamBuf::from_param_list(&list).to_owned();
1830 assert!(!owned.overflowed());
1831 }
1832
1833 #[test]
1834 fn owned_param_size_is_pointer_sized_per_field() {
1835 assert!(std::mem::size_of::<ParamBufOwned>() <= 5 * std::mem::size_of::<usize>());
1839 assert!(std::mem::size_of::<ParamList>() > 1024);
1840 assert!(std::mem::size_of::<ParamBufOwned>() * 16 < std::mem::size_of::<ParamList>());
1841 }
1842
1843 #[cfg(feature = "serde")]
1844 #[test]
1845 fn param_buf_owned_serde_shape_unchanged() {
1846 let owned = ParamBufOwned::new(&[b"1", b"22"]);
1849 let json = serde_json::to_string(&owned).unwrap();
1850 assert_eq!(json, r#"{"params":[[49],[50,50]]}"#);
1851 }
1852}