@@ 1,6 1,5 @@
use crate::ansi::{AnsiCode, ControlSequenceIntroducer};
use std::collections::VecDeque;
-use std::convert::TryInto;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
@@ 10,6 9,7 @@ pub enum Error {
UnknownPabloDraw24BitColorParameterFormat(Vec<u16>),
ParameterToColor(std::num::TryFromIntError),
ApplyingUnknownParameter(u16),
+ ColorValueOutOfBounds(u16),
}
type Result<T> = std::result::Result<T, Error>;
@@ 78,6 78,14 @@ impl Color {
}
}
+fn parse_color(parameter: u16) -> Result<u8> {
+ if parameter < 256 {
+ Ok(parameter as u8)
+ } else {
+ Err(Error::ColorValueOutOfBounds(parameter))
+ }
+}
+
#[derive(PartialEq, Clone)]
struct Style {
background: Color,
@@ 96,7 104,11 @@ impl Style {
}
}
- fn parse(mut self, parameters: &[u16], introducer: &ControlSequenceIntroducer) -> Result<Style> {
+ fn parse(
+ mut self,
+ parameters: &[u16],
+ introducer: &ControlSequenceIntroducer,
+ ) -> Result<Style> {
match introducer {
ControlSequenceIntroducer::SelectGraphicRendition => {
for parameter in parameters {
@@ 112,22 124,18 @@ impl Style {
match parameters {
&[0, red, green, blue] => {
- self.background = Color::True(
- red.try_into()?,
- green.try_into()?,
- blue.try_into()?,
- )
+ self.background =
+ Color::True(parse_color(red)?, parse_color(green)?, parse_color(blue)?)
}
&[1, red, green, blue] => {
- self.foreground = Color::True(
- red.try_into()?,
- green.try_into()?,
- blue.try_into()?,
- )
+ self.foreground =
+ Color::True(parse_color(red)?, parse_color(green)?, parse_color(blue)?)
}
- _ => Err(Error::UnknownPabloDraw24BitColorParameterFormat(parameters.to_vec()))?,
+ _ => Err(Error::UnknownPabloDraw24BitColorParameterFormat(
+ parameters.to_vec(),
+ ))?,
}
- },
+ }
_ => Err(Error::UnsupportedCsiForStyleParsing(introducer.clone()))?,
}
@@ 290,7 298,11 @@ where
if self.output_buffer.is_empty() {
match self.codes.next() {
- Some(code) => self.handle_code(code),
+ Some(code) => {
+ if let Err(error) = self.handle_code(code) {
+ return Some(Err(error));
+ }
+ }
None => {
self.finish();
self.state = AdapterState::Finished;
@@ 366,7 378,7 @@ where
}
}
- fn handle_code(&mut self, code: AnsiCode) {
+ fn handle_code(&mut self, code: AnsiCode) -> Result<()> {
self.handle_line_end();
match code {
@@ 442,7 454,7 @@ where
}
ControlSequenceIntroducer::SelectGraphicRendition
| ControlSequenceIntroducer::PabloDraw24BitColor => {
- let new_brush = self.brush.clone().parse(¶meters, &introducer).unwrap();
+ let new_brush = self.brush.clone().parse(¶meters, &introducer)?;
if self.brush != new_brush {
let difference_params = new_brush.render_difference(
@@ 529,6 541,8 @@ where
}
self.push_boundary();
+
+ Ok(())
}
fn reset_terminal(&mut self) {