Added Ctrl/Alt/Shift+Navigation key support.
This commit is contained in:
parent
189222555e
commit
d57468cdc1
414
src/event.rs
414
src/event.rs
|
@ -57,16 +57,44 @@ pub enum Key {
|
||||||
Backspace,
|
Backspace,
|
||||||
/// Left arrow.
|
/// Left arrow.
|
||||||
Left,
|
Left,
|
||||||
|
/// Shift Left arrow.
|
||||||
|
ShiftLeft,
|
||||||
|
/// Alt Left arrow.
|
||||||
|
AltLeft,
|
||||||
|
/// Ctrl Left arrow.
|
||||||
|
CtrlLeft,
|
||||||
/// Right arrow.
|
/// Right arrow.
|
||||||
Right,
|
Right,
|
||||||
|
/// Shift Right arrow.
|
||||||
|
ShiftRight,
|
||||||
|
/// Alt Right arrow.
|
||||||
|
AltRight,
|
||||||
|
/// Ctrl Right arrow.
|
||||||
|
CtrlRight,
|
||||||
/// Up arrow.
|
/// Up arrow.
|
||||||
Up,
|
Up,
|
||||||
|
/// Shift Up arrow.
|
||||||
|
ShiftUp,
|
||||||
|
/// Alt Up arrow.
|
||||||
|
AltUp,
|
||||||
|
/// Ctrl Up arrow.
|
||||||
|
CtrlUp,
|
||||||
/// Down arrow.
|
/// Down arrow.
|
||||||
Down,
|
Down,
|
||||||
|
/// Shift Down arrow.
|
||||||
|
ShiftDown,
|
||||||
|
/// Alt Down arrow.
|
||||||
|
AltDown,
|
||||||
|
/// Ctrl Down arrow
|
||||||
|
CtrlDown,
|
||||||
/// Home key.
|
/// Home key.
|
||||||
Home,
|
Home,
|
||||||
|
/// Ctrl Home key.
|
||||||
|
CtrlHome,
|
||||||
/// End key.
|
/// End key.
|
||||||
End,
|
End,
|
||||||
|
/// Ctrl End key.
|
||||||
|
CtrlEnd,
|
||||||
/// Page Up key.
|
/// Page Up key.
|
||||||
PageUp,
|
PageUp,
|
||||||
/// Page Down key.
|
/// Page Down key.
|
||||||
|
@ -100,30 +128,31 @@ pub enum Key {
|
||||||
|
|
||||||
/// Parse an Event from `item` and possibly subsequent bytes through `iter`.
|
/// Parse an Event from `item` and possibly subsequent bytes through `iter`.
|
||||||
pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
|
pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
|
||||||
where I: Iterator<Item = Result<u8, Error>>
|
where
|
||||||
|
I: Iterator<Item = Result<u8, Error>>,
|
||||||
{
|
{
|
||||||
let error = Error::new(ErrorKind::Other, "Could not parse an event");
|
let error = Error::new(ErrorKind::Other, "Could not parse an event");
|
||||||
match item {
|
match item {
|
||||||
b'\x1B' => {
|
b'\x1B' => {
|
||||||
// This is an escape character, leading a control sequence.
|
// This is an escape character, leading a control sequence.
|
||||||
Ok(match iter.next() {
|
Ok(match iter.next() {
|
||||||
Some(Ok(b'O')) => {
|
Some(Ok(b'O')) => {
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
// F1-F4
|
// F1-F4
|
||||||
Some(Ok(val @ b'P'..=b'S')) => Event::Key(Key::F(1 + val - b'P')),
|
Some(Ok(val @ b'P'..=b'S')) => Event::Key(Key::F(1 + val - b'P')),
|
||||||
_ => return Err(error),
|
_ => return Err(error),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
Some(Ok(b'[')) => {
|
||||||
Some(Ok(b'[')) => {
|
// This is a CSI sequence.
|
||||||
// This is a CSI sequence.
|
parse_csi(iter).ok_or(error)?
|
||||||
parse_csi(iter).ok_or(error)?
|
}
|
||||||
}
|
Some(Ok(c)) => {
|
||||||
Some(Ok(c)) => {
|
let ch = parse_utf8_char(c, iter)?;
|
||||||
let ch = parse_utf8_char(c, iter)?;
|
Event::Key(Key::Alt(ch))
|
||||||
Event::Key(Key::Alt(ch))
|
}
|
||||||
}
|
Some(Err(_)) | None => return Err(error),
|
||||||
Some(Err(_)) | None => return Err(error),
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))),
|
b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))),
|
||||||
b'\t' => Ok(Event::Key(Key::Char('\t'))),
|
b'\t' => Ok(Event::Key(Key::Char('\t'))),
|
||||||
|
@ -131,12 +160,10 @@ pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
|
||||||
c @ b'\x01'..=b'\x1A' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
|
c @ b'\x01'..=b'\x1A' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
|
||||||
c @ b'\x1C'..=b'\x1F' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char))),
|
c @ b'\x1C'..=b'\x1F' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char))),
|
||||||
b'\0' => Ok(Event::Key(Key::Null)),
|
b'\0' => Ok(Event::Key(Key::Null)),
|
||||||
c => {
|
c => Ok({
|
||||||
Ok({
|
let ch = parse_utf8_char(c, iter)?;
|
||||||
let ch = parse_utf8_char(c, iter)?;
|
Event::Key(Key::Char(ch))
|
||||||
Event::Key(Key::Char(ch))
|
}),
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,179 +171,212 @@ pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
|
||||||
///
|
///
|
||||||
/// Returns None if an unrecognized sequence is found.
|
/// Returns None if an unrecognized sequence is found.
|
||||||
fn parse_csi<I>(iter: &mut I) -> Option<Event>
|
fn parse_csi<I>(iter: &mut I) -> Option<Event>
|
||||||
where I: Iterator<Item = Result<u8, Error>>
|
where
|
||||||
|
I: Iterator<Item = Result<u8, Error>>,
|
||||||
{
|
{
|
||||||
Some(match iter.next() {
|
Some(match iter.next() {
|
||||||
Some(Ok(b'[')) => match iter.next() {
|
Some(Ok(b'[')) => match iter.next() {
|
||||||
Some(Ok(val @ b'A'..=b'E')) => Event::Key(Key::F(1 + val - b'A')),
|
Some(Ok(val @ b'A'..=b'E')) => Event::Key(Key::F(1 + val - b'A')),
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
Some(Ok(b'D')) => Event::Key(Key::Left),
|
|
||||||
Some(Ok(b'C')) => Event::Key(Key::Right),
|
|
||||||
Some(Ok(b'A')) => Event::Key(Key::Up),
|
|
||||||
Some(Ok(b'B')) => Event::Key(Key::Down),
|
|
||||||
Some(Ok(b'H')) => Event::Key(Key::Home),
|
|
||||||
Some(Ok(b'F')) => Event::Key(Key::End),
|
|
||||||
Some(Ok(b'Z')) => Event::Key(Key::BackTab),
|
|
||||||
Some(Ok(b'M')) => {
|
|
||||||
// X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only).
|
|
||||||
let mut next = || iter.next().unwrap().unwrap();
|
|
||||||
|
|
||||||
let cb = next() as i8 - 32;
|
|
||||||
// (1, 1) are the coords for upper left.
|
|
||||||
let cx = next().saturating_sub(32) as u16;
|
|
||||||
let cy = next().saturating_sub(32) as u16;
|
|
||||||
Event::Mouse(match cb & 0b11 {
|
|
||||||
0 => {
|
|
||||||
if cb & 0x40 != 0 {
|
|
||||||
MouseEvent::Press(MouseButton::WheelUp, cx, cy)
|
|
||||||
} else {
|
|
||||||
MouseEvent::Press(MouseButton::Left, cx, cy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
if cb & 0x40 != 0 {
|
|
||||||
MouseEvent::Press(MouseButton::WheelDown, cx, cy)
|
|
||||||
} else {
|
|
||||||
MouseEvent::Press(MouseButton::Middle, cx, cy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2 => MouseEvent::Press(MouseButton::Right, cx, cy),
|
|
||||||
3 => MouseEvent::Release(cx, cy),
|
|
||||||
_ => return None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(Ok(b'<')) => {
|
|
||||||
// xterm mouse encoding:
|
|
||||||
// ESC [ < Cb ; Cx ; Cy (;) (M or m)
|
|
||||||
let mut buf = Vec::new();
|
|
||||||
let mut c = iter.next().unwrap().unwrap();
|
|
||||||
while match c {
|
|
||||||
b'm' | b'M' => false,
|
|
||||||
_ => true,
|
|
||||||
} {
|
|
||||||
buf.push(c);
|
|
||||||
c = iter.next().unwrap().unwrap();
|
|
||||||
}
|
|
||||||
let str_buf = String::from_utf8(buf).unwrap();
|
|
||||||
let nums = &mut str_buf.split(';');
|
|
||||||
|
|
||||||
let cb = nums.next()
|
|
||||||
.unwrap()
|
|
||||||
.parse::<u16>()
|
|
||||||
.unwrap();
|
|
||||||
let cx = nums.next()
|
|
||||||
.unwrap()
|
|
||||||
.parse::<u16>()
|
|
||||||
.unwrap();
|
|
||||||
let cy = nums.next()
|
|
||||||
.unwrap()
|
|
||||||
.parse::<u16>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let event = match cb {
|
|
||||||
0..=2 | 64..=65 => {
|
|
||||||
let button = match cb {
|
|
||||||
0 => MouseButton::Left,
|
|
||||||
1 => MouseButton::Middle,
|
|
||||||
2 => MouseButton::Right,
|
|
||||||
64 => MouseButton::WheelUp,
|
|
||||||
65 => MouseButton::WheelDown,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
match c {
|
|
||||||
b'M' => MouseEvent::Press(button, cx, cy),
|
|
||||||
b'm' => MouseEvent::Release(cx, cy),
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
32 => MouseEvent::Hold(cx, cy),
|
|
||||||
3 => MouseEvent::Release(cx, cy),
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
},
|
||||||
|
Some(Ok(b'1')) => {
|
||||||
|
iter.next(); // Consume next char (;)
|
||||||
|
match iter.next() {
|
||||||
|
Some(Ok(b'2')) => { // Shift Modifier
|
||||||
|
match iter.next() {
|
||||||
|
Some(Ok(b'D')) => Event::Key(Key::ShiftLeft),
|
||||||
|
Some(Ok(b'C')) => Event::Key(Key::ShiftRight),
|
||||||
|
Some(Ok(b'A')) => Event::Key(Key::ShiftUp),
|
||||||
|
Some(Ok(b'B')) => Event::Key(Key::ShiftDown),
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ok(b'3')) => { // Alt Modifier
|
||||||
|
match iter.next() {
|
||||||
|
Some(Ok(b'D')) => Event::Key(Key::AltLeft),
|
||||||
|
Some(Ok(b'C')) => Event::Key(Key::AltRight),
|
||||||
|
Some(Ok(b'A')) => Event::Key(Key::AltUp),
|
||||||
|
Some(Ok(b'B')) => Event::Key(Key::AltDown),
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ok(b'5')) => { // Ctrl Modifier
|
||||||
|
match iter.next() {
|
||||||
|
Some(Ok(b'D')) => Event::Key(Key::CtrlLeft),
|
||||||
|
Some(Ok(b'C')) => Event::Key(Key::CtrlRight),
|
||||||
|
Some(Ok(b'A')) => Event::Key(Key::CtrlUp),
|
||||||
|
Some(Ok(b'B')) => Event::Key(Key::CtrlDown),
|
||||||
|
Some(Ok(b'H')) => Event::Key(Key::CtrlHome),
|
||||||
|
Some(Ok(b'F')) => Event::Key(Key::CtrlEnd),
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ok(b'D')) => Event::Key(Key::Left),
|
||||||
|
Some(Ok(b'C')) => Event::Key(Key::Right),
|
||||||
|
Some(Ok(b'A')) => Event::Key(Key::Up),
|
||||||
|
Some(Ok(b'B')) => Event::Key(Key::Down),
|
||||||
|
Some(Ok(b'H')) => Event::Key(Key::Home),
|
||||||
|
Some(Ok(b'F')) => Event::Key(Key::End),
|
||||||
|
Some(Ok(b'Z')) => Event::Key(Key::BackTab),
|
||||||
|
Some(Ok(b'M')) => {
|
||||||
|
// X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only).
|
||||||
|
let mut next = || iter.next().unwrap().unwrap();
|
||||||
|
|
||||||
Event::Mouse(event)
|
let cb = next() as i8 - 32;
|
||||||
}
|
// (1, 1) are the coords for upper left.
|
||||||
Some(Ok(c @ b'0'..=b'9')) => {
|
let cx = next().saturating_sub(32) as u16;
|
||||||
// Numbered escape code.
|
let cy = next().saturating_sub(32) as u16;
|
||||||
let mut buf = Vec::new();
|
Event::Mouse(match cb & 0b11 {
|
||||||
buf.push(c);
|
0 => {
|
||||||
let mut c = iter.next().unwrap().unwrap();
|
if cb & 0x40 != 0 {
|
||||||
// The final byte of a CSI sequence can be in the range 64-126, so
|
MouseEvent::Press(MouseButton::WheelUp, cx, cy)
|
||||||
// let's keep reading anything else.
|
} else {
|
||||||
while c < 64 || c > 126 {
|
MouseEvent::Press(MouseButton::Left, cx, cy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
if cb & 0x40 != 0 {
|
||||||
|
MouseEvent::Press(MouseButton::WheelDown, cx, cy)
|
||||||
|
} else {
|
||||||
|
MouseEvent::Press(MouseButton::Middle, cx, cy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 => MouseEvent::Press(MouseButton::Right, cx, cy),
|
||||||
|
3 => MouseEvent::Release(cx, cy),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(Ok(b'<')) => {
|
||||||
|
// xterm mouse encoding:
|
||||||
|
// ESC [ < Cb ; Cx ; Cy (;) (M or m)
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let mut c = iter.next().unwrap().unwrap();
|
||||||
|
while match c {
|
||||||
|
b'm' | b'M' => false,
|
||||||
|
_ => true,
|
||||||
|
} {
|
||||||
|
buf.push(c);
|
||||||
|
c = iter.next().unwrap().unwrap();
|
||||||
|
}
|
||||||
|
let str_buf = String::from_utf8(buf).unwrap();
|
||||||
|
let nums = &mut str_buf.split(';');
|
||||||
|
|
||||||
|
let cb = nums.next().unwrap().parse::<u16>().unwrap();
|
||||||
|
let cx = nums.next().unwrap().parse::<u16>().unwrap();
|
||||||
|
let cy = nums.next().unwrap().parse::<u16>().unwrap();
|
||||||
|
|
||||||
|
let event = match cb {
|
||||||
|
0..=2 | 64..=65 => {
|
||||||
|
let button = match cb {
|
||||||
|
0 => MouseButton::Left,
|
||||||
|
1 => MouseButton::Middle,
|
||||||
|
2 => MouseButton::Right,
|
||||||
|
64 => MouseButton::WheelUp,
|
||||||
|
65 => MouseButton::WheelDown,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
match c {
|
||||||
|
b'M' => MouseEvent::Press(button, cx, cy),
|
||||||
|
b'm' => MouseEvent::Release(cx, cy),
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
32 => MouseEvent::Hold(cx, cy),
|
||||||
|
3 => MouseEvent::Release(cx, cy),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Event::Mouse(event)
|
||||||
|
}
|
||||||
|
Some(Ok(c @ b'0'..=b'9')) => {
|
||||||
|
// Numbered escape code.
|
||||||
|
let mut buf = Vec::new();
|
||||||
buf.push(c);
|
buf.push(c);
|
||||||
c = iter.next().unwrap().unwrap();
|
let mut c = iter.next().unwrap().unwrap();
|
||||||
}
|
// The final byte of a CSI sequence can be in the range 64-126, so
|
||||||
|
// let's keep reading anything else.
|
||||||
match c {
|
while c < 64 || c > 126 {
|
||||||
// rxvt mouse encoding:
|
buf.push(c);
|
||||||
// ESC [ Cb ; Cx ; Cy ; M
|
c = iter.next().unwrap().unwrap();
|
||||||
b'M' => {
|
|
||||||
let str_buf = String::from_utf8(buf).unwrap();
|
|
||||||
|
|
||||||
let nums: Vec<u16> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
|
|
||||||
|
|
||||||
let cb = nums[0];
|
|
||||||
let cx = nums[1];
|
|
||||||
let cy = nums[2];
|
|
||||||
|
|
||||||
let event = match cb {
|
|
||||||
32 => MouseEvent::Press(MouseButton::Left, cx, cy),
|
|
||||||
33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
|
|
||||||
34 => MouseEvent::Press(MouseButton::Right, cx, cy),
|
|
||||||
35 => MouseEvent::Release(cx, cy),
|
|
||||||
64 => MouseEvent::Hold(cx, cy),
|
|
||||||
96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Event::Mouse(event)
|
|
||||||
}
|
}
|
||||||
// Special key code.
|
|
||||||
b'~' => {
|
|
||||||
let str_buf = String::from_utf8(buf).unwrap();
|
|
||||||
|
|
||||||
// This CSI sequence can be a list of semicolon-separated
|
match c {
|
||||||
// numbers.
|
// rxvt mouse encoding:
|
||||||
let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
|
// ESC [ Cb ; Cx ; Cy ; M
|
||||||
|
b'M' => {
|
||||||
|
let str_buf = String::from_utf8(buf).unwrap();
|
||||||
|
|
||||||
if nums.is_empty() {
|
let nums: Vec<u16> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
|
||||||
return None;
|
|
||||||
|
let cb = nums[0];
|
||||||
|
let cx = nums[1];
|
||||||
|
let cy = nums[2];
|
||||||
|
|
||||||
|
let event = match cb {
|
||||||
|
32 => MouseEvent::Press(MouseButton::Left, cx, cy),
|
||||||
|
33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
|
||||||
|
34 => MouseEvent::Press(MouseButton::Right, cx, cy),
|
||||||
|
35 => MouseEvent::Release(cx, cy),
|
||||||
|
64 => MouseEvent::Hold(cx, cy),
|
||||||
|
96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Event::Mouse(event)
|
||||||
}
|
}
|
||||||
|
// Special key code.
|
||||||
|
b'~' => {
|
||||||
|
let str_buf = String::from_utf8(buf).unwrap();
|
||||||
|
|
||||||
// TODO: handle multiple values for key modififiers (ex: values
|
// This CSI sequence can be a list of semicolon-separated
|
||||||
// [3, 2] means Shift+Delete)
|
// numbers.
|
||||||
if nums.len() > 1 {
|
let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
match nums[0] {
|
if nums.is_empty() {
|
||||||
1 | 7 => Event::Key(Key::Home),
|
return None;
|
||||||
2 => Event::Key(Key::Insert),
|
}
|
||||||
3 => Event::Key(Key::Delete),
|
|
||||||
4 | 8 => Event::Key(Key::End),
|
// TODO: handle multiple values for key modififiers (ex: values
|
||||||
5 => Event::Key(Key::PageUp),
|
// [3, 2] means Shift+Delete)
|
||||||
6 => Event::Key(Key::PageDown),
|
if nums.len() > 1 {
|
||||||
v @ 11..=15 => Event::Key(Key::F(v - 10)),
|
return None;
|
||||||
v @ 17..=21 => Event::Key(Key::F(v - 11)),
|
}
|
||||||
v @ 23..=24 => Event::Key(Key::F(v - 12)),
|
|
||||||
_ => return None,
|
match nums[0] {
|
||||||
|
1 | 7 => Event::Key(Key::Home),
|
||||||
|
2 => Event::Key(Key::Insert),
|
||||||
|
3 => Event::Key(Key::Delete),
|
||||||
|
4 | 8 => Event::Key(Key::End),
|
||||||
|
5 => Event::Key(Key::PageUp),
|
||||||
|
6 => Event::Key(Key::PageDown),
|
||||||
|
v @ 11..=15 => Event::Key(Key::F(v - 10)),
|
||||||
|
v @ 17..=21 => Event::Key(Key::F(v - 11)),
|
||||||
|
v @ 23..=24 => Event::Key(Key::F(v - 12)),
|
||||||
|
v => {
|
||||||
|
println!("{:?}", v);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => return None,
|
||||||
}
|
}
|
||||||
_ => return None,
|
|
||||||
}
|
}
|
||||||
}
|
_ => return None,
|
||||||
_ => return None,
|
})
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse `c` as either a single byte ASCII char or a variable size UTF-8 char.
|
/// Parse `c` as either a single byte ASCII char or a variable size UTF-8 char.
|
||||||
fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
|
fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
|
||||||
where I: Iterator<Item = Result<u8, Error>>
|
where
|
||||||
|
I: Iterator<Item = Result<u8, Error>>,
|
||||||
{
|
{
|
||||||
let error = Err(Error::new(ErrorKind::Other, "Input character is not valid UTF-8"));
|
let error = Err(Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
"Input character is not valid UTF-8",
|
||||||
|
));
|
||||||
if c.is_ascii() {
|
if c.is_ascii() {
|
||||||
Ok(c as char)
|
Ok(c as char)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue