Skip to content

Commit cbbdde3

Browse files
committed
Split opauqe_*() functions into sos_*(), pm_*(), apc_*().
Split the `opaque_[start|put|end]()` set of functions into 3 different sets of functions for SOS, PM and APC sequences.
1 parent 790e34e commit cbbdde3

File tree

1 file changed

+158
-28
lines changed

1 file changed

+158
-28
lines changed

src/lib.rs

Lines changed: 158 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub struct Parser<const OSC_RAW_BUF_SIZE: usize = MAX_OSC_RAW> {
9090
osc_num_params: usize,
9191
ignoring: bool,
9292
utf8_parser: utf8::Parser,
93+
opaque_sequence_kind: Option<OpaqueSequenceKind>,
9394
}
9495

9596
impl Parser {
@@ -385,10 +386,34 @@ impl<const OSC_RAW_BUF_SIZE: usize> Parser<OSC_RAW_BUF_SIZE> {
385386
// byte value, this branch is unreachable.
386387
_ => unreachable!("invalid opaque sequence kind"),
387388
};
388-
performer.opaque_start(kind)
389+
self.opaque_sequence_kind = Some(kind);
390+
match kind {
391+
OpaqueSequenceKind::Sos => performer.sos_start(),
392+
OpaqueSequenceKind::Pm => performer.pm_start(),
393+
OpaqueSequenceKind::Apc => performer.apc_start(),
394+
}
395+
},
396+
Action::OpaquePut => {
397+
match self.opaque_sequence_kind {
398+
Some(OpaqueSequenceKind::Sos) => performer.sos_put(byte),
399+
Some(OpaqueSequenceKind::Pm) => performer.pm_put(byte),
400+
Some(OpaqueSequenceKind::Apc) => performer.apc_put(byte),
401+
// This action is only triggered inside the OpaqueString state, which requires
402+
// that the opaque_sequence_kind is set to a Some(x) value.
403+
None => unreachable!("opaque sequence kind not set"),
404+
}
405+
},
406+
Action::OpaqueEnd => {
407+
match self.opaque_sequence_kind {
408+
Some(OpaqueSequenceKind::Sos) => performer.sos_end(),
409+
Some(OpaqueSequenceKind::Pm) => performer.pm_end(),
410+
Some(OpaqueSequenceKind::Apc) => performer.apc_end(),
411+
// This action is only triggered inside the OpaqueString state, which requires
412+
// that the opaque_sequence_kind is set to a Some(x) value.
413+
None => unreachable!("opaque sequence kind not set"),
414+
}
415+
self.opaque_sequence_kind = None;
389416
},
390-
Action::OpaquePut => performer.opaque_put(byte),
391-
Action::OpaqueEnd => performer.opaque_end(),
392417
}
393418
}
394419
}
@@ -454,19 +479,41 @@ pub trait Perform {
454479
/// subsequent characters were ignored.
455480
fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) {}
456481

457-
/// The start of an opaque sequence (SOS, PM or APC) has been detected.
482+
/// The start of an SOS sequence has been detected.
458483
///
459-
/// The `kind` parameter indicates the type of sequence that was started.
484+
/// Until the SOS sequence ends (at which point `sos_end` will be called), invalid
485+
/// characters will be ignored while valid characters will be passed on to `sos_put`.
486+
fn sos_start(&mut self) {}
487+
488+
/// A byte has been received as part of an ongoing SOS sequence.
489+
fn sos_put(&mut self, _byte: u8) {}
490+
491+
/// We've reached the end of the ongoing SOS sequence.
492+
fn sos_end(&mut self) {}
493+
494+
/// The start of a PM sequence has been detected.
495+
///
496+
/// Until the PM sequence ends (at which point `pm_end` will be called), invalid
497+
/// characters will be ignored while valid characters will be passed on to `pm_put`.
498+
fn pm_start(&mut self) {}
499+
500+
/// A byte has been received as part of an ongoing PM sequence.
501+
fn pm_put(&mut self, _byte: u8) {}
502+
503+
/// We've reached the end of the ongoing PM sequence.
504+
fn pm_end(&mut self) {}
505+
506+
/// The start of an APC sequence has been detected.
460507
///
461-
/// Until the opaque sequence ends (at which point `opaque_end` will be called), invalid
462-
/// characters will be ignored while valid characters will be passed on to `opaque_put`.
463-
fn opaque_start(&mut self, _kind: OpaqueSequenceKind) {}
508+
/// Until the APC sequence ends (at which point `apc_end` will be called), invalid
509+
/// characters will be ignored while valid characters will be passed on to `apc_put`.
510+
fn apc_start(&mut self) {}
464511

465-
/// We've reached the end of the ongoing opaque sequence (SOS, PM or APC).
466-
fn opaque_end(&mut self) {}
512+
/// A byte has been received as part of an ongoing APC sequence.
513+
fn apc_put(&mut self, _byte: u8) {}
467514

468-
/// A byte has been received as part of an ongoing opaque sequence.
469-
fn opaque_put(&mut self, _byte: u8) {}
515+
/// We've reached the end of the ongoing APC sequence.
516+
fn apc_end(&mut self) {}
470517
}
471518

472519
#[cfg(all(test, feature = "no_std"))]
@@ -499,9 +546,15 @@ mod tests {
499546
DcsHook(Vec<Vec<u16>>, Vec<u8>, bool, char),
500547
DcsPut(u8),
501548
DcsUnhook,
502-
OpaqueStart(OpaqueSequenceKind),
503-
OpaquePut(u8),
504-
OpaqueEnd,
549+
SosStart,
550+
SosPut(u8),
551+
SosEnd,
552+
PmStart,
553+
PmPut(u8),
554+
PmEnd,
555+
ApcStart,
556+
ApcPut(u8),
557+
ApcEnd,
505558
}
506559

507560
impl Perform for Dispatcher {
@@ -535,16 +588,40 @@ mod tests {
535588
self.dispatched.push(Sequence::DcsUnhook);
536589
}
537590

538-
fn opaque_start(&mut self, _kind: OpaqueSequenceKind) {
539-
self.dispatched.push(Sequence::OpaqueStart(_kind));
591+
fn sos_start(&mut self) {
592+
self.dispatched.push(Sequence::SosStart);
540593
}
541594

542-
fn opaque_put(&mut self, byte: u8) {
543-
self.dispatched.push(Sequence::OpaquePut(byte));
595+
fn sos_put(&mut self, byte: u8) {
596+
self.dispatched.push(Sequence::SosPut(byte));
544597
}
545598

546-
fn opaque_end(&mut self) {
547-
self.dispatched.push(Sequence::OpaqueEnd);
599+
fn sos_end(&mut self) {
600+
self.dispatched.push(Sequence::SosEnd);
601+
}
602+
603+
fn pm_start(&mut self) {
604+
self.dispatched.push(Sequence::PmStart);
605+
}
606+
607+
fn pm_put(&mut self, byte: u8) {
608+
self.dispatched.push(Sequence::PmPut(byte));
609+
}
610+
611+
fn pm_end(&mut self) {
612+
self.dispatched.push(Sequence::PmEnd);
613+
}
614+
615+
fn apc_start(&mut self) {
616+
self.dispatched.push(Sequence::ApcStart);
617+
}
618+
619+
fn apc_put(&mut self, byte: u8) {
620+
self.dispatched.push(Sequence::ApcPut(byte));
621+
}
622+
623+
fn apc_end(&mut self) {
624+
self.dispatched.push(Sequence::ApcEnd);
548625
}
549626
}
550627

@@ -682,6 +759,56 @@ mod tests {
682759
}
683760
}
684761

762+
#[test]
763+
fn parse_sos() {
764+
const INPUT: &[u8] = b"\x1bXabc\x1b\\";
765+
766+
// Test with ESC \ terminator.
767+
768+
let mut dispatcher = Dispatcher::default();
769+
let mut parser = Parser::new();
770+
771+
for byte in INPUT {
772+
parser.advance(&mut dispatcher, *byte);
773+
}
774+
assert_eq!(dispatcher.dispatched.len(), 6);
775+
assert_eq!(
776+
dispatcher.dispatched[0..5],
777+
vec![
778+
Sequence::SosStart,
779+
Sequence::SosPut(b'a'),
780+
Sequence::SosPut(b'b'),
781+
Sequence::SosPut(b'c'),
782+
Sequence::SosEnd,
783+
]
784+
)
785+
}
786+
787+
#[test]
788+
fn parse_pm() {
789+
const INPUT: &[u8] = b"\x1b^abc\x1b\\";
790+
791+
// Test with ESC \ terminator.
792+
793+
let mut dispatcher = Dispatcher::default();
794+
let mut parser = Parser::new();
795+
796+
for byte in INPUT {
797+
parser.advance(&mut dispatcher, *byte);
798+
}
799+
assert_eq!(dispatcher.dispatched.len(), 6);
800+
assert_eq!(
801+
dispatcher.dispatched[0..5],
802+
vec![
803+
Sequence::PmStart,
804+
Sequence::PmPut(b'a'),
805+
Sequence::PmPut(b'b'),
806+
Sequence::PmPut(b'c'),
807+
Sequence::PmEnd,
808+
]
809+
)
810+
}
811+
685812
#[test]
686813
fn parse_apc() {
687814
const INPUT: &[u8] = b"\x1b_abc\x1b\\";
@@ -695,13 +822,16 @@ mod tests {
695822
parser.advance(&mut dispatcher, *byte);
696823
}
697824
assert_eq!(dispatcher.dispatched.len(), 6);
698-
assert_eq!(dispatcher.dispatched[0..5], vec![
699-
Sequence::OpaqueStart(OpaqueSequenceKind::Apc),
700-
Sequence::OpaquePut(b'a'),
701-
Sequence::OpaquePut(b'b'),
702-
Sequence::OpaquePut(b'c'),
703-
Sequence::OpaqueEnd,
704-
])
825+
assert_eq!(
826+
dispatcher.dispatched[0..5],
827+
vec![
828+
Sequence::ApcStart,
829+
Sequence::ApcPut(b'a'),
830+
Sequence::ApcPut(b'b'),
831+
Sequence::ApcPut(b'c'),
832+
Sequence::ApcEnd,
833+
]
834+
)
705835
}
706836

707837
#[test]

0 commit comments

Comments
 (0)