Merge pull request #88 from luisholanda/rework-event-parsing

Take msgv::Value by value in bridge::events
macos-click-through
Keith Simmons 5 years ago committed by GitHub
commit 1c299c65b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1616
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -12,7 +12,7 @@ skribo = { git = "https://github.com/linebender/skribo" }
lru = "0.4.3" lru = "0.4.3"
skulpin = { git = "https://github.com/kethku/skulpin", branch = "winit_20" } skulpin = { git = "https://github.com/kethku/skulpin", branch = "winit_20" }
derive-new = "0.5" derive-new = "0.5"
rmpv = "0.4.2" rmpv = "0.4.4"
rust-embed = { version = "5.2.0", features = ["debug-embed"] } rust-embed = { version = "5.2.0", features = ["debug-embed"] }
image = "0.22.3" image = "0.22.3"
nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", features = [ "use_tokio" ] } nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", features = [ "use_tokio" ] }

@ -1,5 +1,6 @@
use std::error; use std::error;
use std::fmt; use std::fmt;
use std::convert::TryInto;
use rmpv::Value; use rmpv::Value;
use skulpin::skia_safe::Color4f; use skulpin::skia_safe::Color4f;
@ -159,494 +160,450 @@ fn unpack_color(packed_color: u64) -> Color4f {
} }
} }
fn parse_array(array_value: &Value) -> Result<&[Value]> { fn extract_values<Arr: AsMut<[Value]>>(values: Vec<Value>, mut arr: Arr) -> Result<Arr>
if let Value::Array(content) = array_value { {
Ok(&content[..]) let arr_ref = arr.as_mut();
if values.len() != arr_ref.len() {
Err(EventParseError::InvalidEventFormat)
} else { } else {
Err(EventParseError::InvalidArray(array_value.clone())) for (i, val) in values.into_iter().enumerate() {
arr_ref[i] = val;
}
Ok(arr)
} }
} }
fn parse_map(map_value: &Value) -> Result<&[(Value, Value)]> { fn parse_array(array_value: Value) -> Result<Vec<Value>> {
if let Value::Map(content) = map_value { array_value.try_into().map_err(EventParseError::InvalidArray)
Ok(&content[..])
} else {
Err(EventParseError::InvalidMap(map_value.clone()))
}
} }
fn parse_string(string_value: &Value) -> Result<&str> { fn parse_map(map_value: Value) -> Result<Vec<(Value, Value)>> {
if let Value::String(content) = string_value { map_value.try_into().map_err(EventParseError::InvalidMap)
content.as_str().ok_or_else(|| EventParseError::InvalidString(string_value.clone()))
} else {
Err(EventParseError::InvalidString(string_value.clone()))
}
} }
fn parse_u64(u64_value: &Value) -> Result<u64> { fn parse_string(string_value: Value) -> Result<String> {
if let Value::Integer(content) = u64_value { string_value.try_into().map_err(EventParseError::InvalidString)
Ok(content.as_u64().ok_or_else(|| EventParseError::InvalidU64(u64_value.clone()))?)
} else {
Err(EventParseError::InvalidU64(u64_value.clone()))
}
} }
fn parse_i64(i64_value: &Value) -> Result<i64> { fn parse_u64(u64_value: Value) -> Result<u64> {
if let Value::Integer(content) = i64_value { u64_value.try_into().map_err(EventParseError::InvalidU64)
Ok(content.as_i64().ok_or_else(|| EventParseError::InvalidI64(i64_value.clone()))?)
} else {
Err(EventParseError::InvalidI64(i64_value.clone()))
}
} }
fn parse_bool(bool_value: &Value) -> Result<bool> { fn parse_i64(i64_value: Value) -> Result<i64> {
if let Value::Boolean(content) = bool_value { i64_value.try_into().map_err(EventParseError::InvalidI64)
Ok(*content)
} else {
Err(EventParseError::InvalidBool(bool_value.clone()))
}
} }
fn parse_set_title(set_title_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_bool(bool_value: Value) -> Result<bool> {
if let [title] = set_title_arguments { bool_value.try_into().map_err(EventParseError::InvalidBool)
Ok(RedrawEvent::SetTitle {
title: parse_string(title)?.to_string()
})
} else {
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_mode_info_set(mode_info_set_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_set_title(set_title_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [_cursor_style_enabled, mode_info] = mode_info_set_arguments { let [title] = extract_values(set_title_arguments, [Value::Nil])?;
let mode_info_values = parse_array(mode_info)?;
let mut cursor_modes = Vec::with_capacity(mode_info_values.len()); Ok(RedrawEvent::SetTitle {
title: parse_string(title)?
for mode_info_value in mode_info_values { })
let info_map = parse_map(mode_info_value)?; }
let mut mode_info = CursorMode::default();
fn parse_mode_info_set(mode_info_set_arguments: Vec<Value>) -> Result<RedrawEvent> {
for (name, value) in info_map { let [_cursor_style_enabled, mode_info] = extract_values(mode_info_set_arguments, [Value::Nil, Value::Nil])?;
match parse_string(name)? {
"cursor_shape" => { let mode_info_values = parse_array(mode_info)?;
mode_info.shape = CursorShape::from_type_name(parse_string(value)?); let mut cursor_modes = Vec::with_capacity(mode_info_values.len());
},
"cell_percentage" => { for mode_info_value in mode_info_values {
mode_info.cell_percentage = Some(parse_u64(value)? as f32 / 100.0); let info_map = parse_map(mode_info_value)?;
}, let mut mode_info = CursorMode::default();
"blinkwait" => {
mode_info.blinkwait = Some(parse_u64(value)?); for (name, value) in info_map {
}, match parse_string(name)?.as_str() {
"blinkon" => { "cursor_shape" => {
mode_info.blinkon = Some(parse_u64(value)?); mode_info.shape = CursorShape::from_type_name(&parse_string(value)?);
}, },
"blinkoff" => { "cell_percentage" => {
mode_info.blinkoff = Some(parse_u64(value)?); mode_info.cell_percentage = Some(parse_u64(value)? as f32 / 100.0);
} },
"attr_id" => { "blinkwait" => {
mode_info.style_id = Some(parse_u64(value)?); mode_info.blinkwait = Some(parse_u64(value)?);
}, },
_ => {} "blinkon" => {
mode_info.blinkon = Some(parse_u64(value)?);
},
"blinkoff" => {
mode_info.blinkoff = Some(parse_u64(value)?);
} }
"attr_id" => {
mode_info.style_id = Some(parse_u64(value)?);
},
_ => {}
} }
cursor_modes.push(mode_info);
} }
Ok(RedrawEvent::ModeInfoSet {
cursor_modes cursor_modes.push(mode_info);
})
} else {
Err(EventParseError::InvalidEventFormat)
} }
Ok(RedrawEvent::ModeInfoSet {
cursor_modes
})
} }
fn parse_option_set(option_set_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_option_set(option_set_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [name, value] = option_set_arguments { let [name, value] = extract_values(option_set_arguments, [Value::Nil, Value::Nil])?;
Ok(RedrawEvent::OptionSet {
gui_option: match parse_string(name)? { let name = parse_string(name)?;
"arabicshape" => GuiOption::AribicShape(parse_bool(value)?),
"ambiwidth" => GuiOption::AmbiWidth(parse_string(value)?.to_string()), Ok(RedrawEvent::OptionSet {
"emoji" => GuiOption::Emoji(parse_bool(value)?), gui_option: match name.as_str() {
"guifont" => GuiOption::GuiFont(parse_string(value)?.to_string()), "arabicshape" => GuiOption::AribicShape(parse_bool(value)?),
"guifontset" => GuiOption::GuiFontSet(parse_string(value)?.to_string()), "ambiwidth" => GuiOption::AmbiWidth(parse_string(value)?),
"guifontwide" => GuiOption::GuiFontWide(parse_string(value)?.to_string()), "emoji" => GuiOption::Emoji(parse_bool(value)?),
"linespace" => GuiOption::LineSpace(parse_u64(value)?), "guifont" => GuiOption::GuiFont(parse_string(value)?),
"pumblend" => GuiOption::Pumblend(parse_u64(value)?), "guifontset" => GuiOption::GuiFontSet(parse_string(value)?),
"showtabline" => GuiOption::ShowTabLine(parse_u64(value)?), "guifontwide" => GuiOption::GuiFontWide(parse_string(value)?),
"termguicolors" => GuiOption::TermGuiColors(parse_bool(value)?), "linespace" => GuiOption::LineSpace(parse_u64(value)?),
unknown_option => GuiOption::Unknown(unknown_option.to_string(), value.clone()) "pumblend" => GuiOption::Pumblend(parse_u64(value)?),
} "showtabline" => GuiOption::ShowTabLine(parse_u64(value)?),
}) "termguicolors" => GuiOption::TermGuiColors(parse_bool(value)?),
} else { _ => GuiOption::Unknown(name, value)
Err(EventParseError::InvalidEventFormat) }
} })
} }
fn parse_mode_change(mode_change_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_mode_change(mode_change_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [_mode, mode_index] = mode_change_arguments { let [_mode, mode_index] = extract_values(mode_change_arguments, [Value::Nil, Value::Nil])?;
Ok(RedrawEvent::ModeChange {
mode_index: parse_u64(mode_index)? Ok(RedrawEvent::ModeChange {
}) mode_index: parse_u64(mode_index)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_grid_resize(grid_resize_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_grid_resize(grid_resize_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id, width, height] = grid_resize_arguments { let [grid_id, width, height] = extract_values(grid_resize_arguments, [Value::Nil, Value::Nil, Value::Nil])?;
Ok(RedrawEvent::Resize {
grid: parse_u64(grid_id)?, width: parse_u64(width)?, height: parse_u64(height)? Ok(RedrawEvent::Resize {
}) grid: parse_u64(grid_id)?,
} else { width: parse_u64(width)?,
Err(EventParseError::InvalidEventFormat) height: parse_u64(height)?
} })
} }
fn parse_default_colors(default_colors_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_default_colors(default_colors_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [ let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil];
foreground, background, special, _term_foreground, _term_background let [foreground, background, special, _term_foreground, _term_background] = extract_values(default_colors_arguments, values)?;
] = default_colors_arguments {
Ok(RedrawEvent::DefaultColorsSet { Ok(RedrawEvent::DefaultColorsSet {
colors: Colors { colors: Colors {
foreground: Some(unpack_color(parse_u64(foreground)?)), foreground: Some(unpack_color(parse_u64(foreground)?)),
background: Some(unpack_color(parse_u64(background)?)), background: Some(unpack_color(parse_u64(background)?)),
special: Some(unpack_color(parse_u64(special)?)), special: Some(unpack_color(parse_u64(special)?)),
} }
}) })
} else {
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_style(style_map: &Value) -> Result<Style> { fn parse_style(style_map: Value) -> Result<Style> {
if let Value::Map(attributes) = style_map { let attributes = parse_map(style_map)?;
let mut style = Style::new(Colors::new(None, None, None));
let mut style = Style::new(Colors::new(None, None, None));
for attribute in attributes {
if let (Value::String(name), value) = attribute { for attribute in attributes {
match (name.as_str().unwrap(), value) { if let (Value::String(name), value) = attribute {
("foreground", Value::Integer(packed_color)) => style.colors.foreground = Some(unpack_color(packed_color.as_u64().unwrap())), match (name.as_str().unwrap(), value) {
("background", Value::Integer(packed_color)) => style.colors.background = Some(unpack_color(packed_color.as_u64().unwrap())), ("foreground", Value::Integer(packed_color)) => style.colors.foreground = Some(unpack_color(packed_color.as_u64().unwrap())),
("special", Value::Integer(packed_color)) => style.colors.special = Some(unpack_color(packed_color.as_u64().unwrap())), ("background", Value::Integer(packed_color)) => style.colors.background = Some(unpack_color(packed_color.as_u64().unwrap())),
("reverse", Value::Boolean(reverse)) => style.reverse = *reverse, ("special", Value::Integer(packed_color)) => style.colors.special = Some(unpack_color(packed_color.as_u64().unwrap())),
("italic", Value::Boolean(italic)) => style.italic = *italic, ("reverse", Value::Boolean(reverse)) => style.reverse = reverse,
("bold", Value::Boolean(bold)) => style.bold = *bold, ("italic", Value::Boolean(italic)) => style.italic = italic,
("strikethrough", Value::Boolean(strikethrough)) => style.strikethrough = *strikethrough, ("bold", Value::Boolean(bold)) => style.bold = bold,
("underline", Value::Boolean(underline)) => style.underline = *underline, ("strikethrough", Value::Boolean(strikethrough)) => style.strikethrough = strikethrough,
("undercurl", Value::Boolean(undercurl)) => style.undercurl = *undercurl, ("underline", Value::Boolean(underline)) => style.underline = underline,
("blend", Value::Integer(blend)) => style.blend = blend.as_u64().unwrap() as u8, ("undercurl", Value::Boolean(undercurl)) => style.undercurl = undercurl,
_ => println!("Ignored style attribute: {}", name) ("blend", Value::Integer(blend)) => style.blend = blend.as_u64().unwrap() as u8,
} _ => println!("Ignored style attribute: {}", name)
} else {
println!("Invalid attribute format");
} }
} else {
println!("Invalid attribute format");
} }
Ok(style)
} else {
Err(EventParseError::InvalidMap(style_map.clone()))
} }
Ok(style)
} }
fn parse_hl_attr_define(hl_attr_define_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_hl_attr_define(hl_attr_define_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [ let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil];
id, attributes, _terminal_attributes, _info let [id, attributes, _terminal_attributes, _info] = extract_values(hl_attr_define_arguments, values)?;
] = hl_attr_define_arguments {
let style = parse_style(attributes)?; let style = parse_style(attributes)?;
Ok(RedrawEvent::HighlightAttributesDefine { id: parse_u64(id)?, style }) Ok(RedrawEvent::HighlightAttributesDefine { id: parse_u64(id)?, style })
} else {
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_grid_line_cell(grid_line_cell: &Value) -> Result<GridLineCell> { fn parse_grid_line_cell(grid_line_cell: Value) -> Result<GridLineCell> {
let cell_contents = parse_array(grid_line_cell)?; fn take_value(val: &mut Value) -> Value {
let text_value = cell_contents.get(0).ok_or(EventParseError::InvalidEventFormat)?; std::mem::replace(val, Value::Nil)
}
let mut cell_contents = parse_array(grid_line_cell)?;
let text_value = cell_contents.first_mut()
.map(|v| take_value(v))
.ok_or(EventParseError::InvalidEventFormat)?;
let highlight_id = cell_contents.get_mut(1).map(|v| take_value(v)).map(parse_u64).transpose()?;
let repeat = cell_contents.get_mut(2).map(|v| take_value(v)).map(parse_u64).transpose()?;
Ok(GridLineCell { Ok(GridLineCell {
text: parse_string(text_value)?.to_string(), text: parse_string(text_value)?,
highlight_id: cell_contents.get(1).map(parse_u64).transpose()?, highlight_id,
repeat: cell_contents.get(2).map(parse_u64).transpose()? repeat
}) })
} }
fn parse_grid_line(grid_line_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_grid_line(grid_line_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id, row, column_start, cells] = grid_line_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::GridLine { let [grid_id, row, column_start, cells] = extract_values(grid_line_arguments, values)?;
grid: parse_u64(grid_id)?,
row: parse_u64(row)?, column_start: parse_u64(column_start)?, Ok(RedrawEvent::GridLine {
cells: parse_array(cells)? grid: parse_u64(grid_id)?,
.into_iter() row: parse_u64(row)?,
.map(parse_grid_line_cell) column_start: parse_u64(column_start)?,
.collect::<Result<Vec<GridLineCell>>>()? cells: parse_array(cells)?
}) .into_iter()
} else { .map(parse_grid_line_cell)
Err(EventParseError::InvalidEventFormat) .collect::<Result<Vec<GridLineCell>>>()?
} })
} }
fn parse_clear(clear_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_clear(clear_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id] = clear_arguments { let [grid_id] = extract_values(clear_arguments, [Value::Nil])?;
Ok(RedrawEvent::Clear { grid: parse_u64(grid_id)? })
} else { Ok(RedrawEvent::Clear { grid: parse_u64(grid_id)? })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_cursor_goto(cursor_goto_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cursor_goto(cursor_goto_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id, column, row] = cursor_goto_arguments { let [grid_id, column, row] = extract_values(cursor_goto_arguments, [Value::Nil, Value::Nil, Value::Nil])?;
Ok(RedrawEvent::CursorGoto {
grid: parse_u64(grid_id)?, row: parse_u64(row)?, column: parse_u64(column)? Ok(RedrawEvent::CursorGoto {
}) grid: parse_u64(grid_id)?,
} else { row: parse_u64(row)?,
Err(EventParseError::InvalidEventFormat) column: parse_u64(column)?
} })
} }
fn parse_grid_scroll(grid_scroll_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_grid_scroll(grid_scroll_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id, top, bottom, left, right, rows, columns] = grid_scroll_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::Scroll { let [grid_id, top, bottom, left, right, rows, columns] = extract_values(grid_scroll_arguments, values)?;
grid: parse_u64(grid_id)?, Ok(RedrawEvent::Scroll {
top: parse_u64(top)?, bottom: parse_u64(bottom)?, grid: parse_u64(grid_id)?,
left: parse_u64(left)?, right: parse_u64(right)?, top: parse_u64(top)?, bottom: parse_u64(bottom)?,
rows: parse_i64(rows)?, columns: parse_i64(columns)? left: parse_u64(left)?, right: parse_u64(right)?,
}) rows: parse_i64(rows)?, columns: parse_i64(columns)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_win_pos(win_pos_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_win_pos(win_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid, window, start_row, start_column, width, height] = win_pos_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::WindowPosition { let [grid, window, start_row, start_column, width, height] = extract_values(win_pos_arguments, values)?;
grid: parse_u64(grid)?,
window: parse_u64(window)?, Ok(RedrawEvent::WindowPosition {
start_row: parse_u64(start_row)?, grid: parse_u64(grid)?,
start_column: parse_u64(start_column)?, window: parse_u64(window)?,
width: parse_u64(width)?, start_row: parse_u64(start_row)?,
height: parse_u64(height)? start_column: parse_u64(start_column)?,
}) width: parse_u64(width)?,
} else { height: parse_u64(height)?
Err(EventParseError::InvalidEventFormat) })
}
} }
fn parse_window_anchor(value: &Value) -> Result<WindowAnchor> { fn parse_window_anchor(value: Value) -> Result<WindowAnchor> {
match parse_string(value).ok() { let value_str = parse_string(value)?;
Some("NW") => Ok(WindowAnchor::NorthWest), match value_str.as_str() {
Some("NE") => Ok(WindowAnchor::NorthEast), "NW" => Ok(WindowAnchor::NorthWest),
Some("SW") => Ok(WindowAnchor::SouthWest), "NE" => Ok(WindowAnchor::NorthEast),
Some("SE") => Ok(WindowAnchor::SouthEast), "SW" => Ok(WindowAnchor::SouthWest),
_ => Err(EventParseError::InvalidWindowAnchor(value.clone())) "SE" => Ok(WindowAnchor::SouthEast),
_ => Err(EventParseError::InvalidWindowAnchor(value_str.into()))
} }
} }
fn parse_win_float_pos(win_float_pos_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_win_float_pos(win_float_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid, window, anchor, anchor_grid, anchor_row, anchor_column, focusable] = win_float_pos_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::WindowFloatPosition { let [grid, window, anchor, anchor_grid, anchor_row, anchor_column, focusable] = extract_values(win_float_pos_arguments, values)?;
grid: parse_u64(grid)?,
window: parse_u64(window)?, Ok(RedrawEvent::WindowFloatPosition {
anchor: parse_window_anchor(anchor)?, grid: parse_u64(grid)?,
anchor_grid: parse_u64(anchor_grid)?, window: parse_u64(window)?,
anchor_row: parse_u64(anchor_row)?, anchor: parse_window_anchor(anchor)?,
anchor_column: parse_u64(anchor_column)?, anchor_grid: parse_u64(anchor_grid)?,
focusable: parse_bool(focusable)? anchor_row: parse_u64(anchor_row)?,
}) anchor_column: parse_u64(anchor_column)?,
} else { focusable: parse_bool(focusable)?
Err(EventParseError::InvalidEventFormat) })
}
} }
fn parse_win_external_pos(win_external_pos_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_win_external_pos(win_external_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid, window] = win_external_pos_arguments { let [grid, window] = extract_values(win_external_pos_arguments, [Value::Nil, Value::Nil])?;
Ok(RedrawEvent::WindowExternalPosition {
grid: parse_u64(grid)?, Ok(RedrawEvent::WindowExternalPosition {
window: parse_u64(window)? grid: parse_u64(grid)?,
}) window: parse_u64(window)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_win_hide(win_hide_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_win_hide(win_hide_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid] = win_hide_arguments { let [grid] = extract_values(win_hide_arguments, [Value::Nil])?;
Ok(RedrawEvent::WindowHide {
grid: parse_u64(grid)? Ok(RedrawEvent::WindowHide {
}) grid: parse_u64(grid)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_win_close(win_close_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_win_close(win_close_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid] = win_close_arguments { let [grid] = extract_values(win_close_arguments, [Value::Nil])?;
Ok(RedrawEvent::WindowClose {
grid: parse_u64(grid)? Ok(RedrawEvent::WindowClose {
}) grid: parse_u64(grid)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_set_pos(msg_set_pos_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_set_pos(msg_set_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid, row, scrolled, separator_character] = msg_set_pos_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::MessageSetPosition { let [grid, row, scrolled, separator_character] = extract_values(msg_set_pos_arguments, values)?;
grid: parse_u64(grid)?,
row: parse_u64(row)?, Ok(RedrawEvent::MessageSetPosition {
scrolled: parse_bool(scrolled)?, grid: parse_u64(grid)?,
separator_character: parse_string(separator_character)?.to_string() row: parse_u64(row)?,
}) scrolled: parse_bool(scrolled)?,
} else { separator_character: parse_string(separator_character)?
Err(EventParseError::InvalidEventFormat) })
}
} }
fn parse_styled_content(line: &Value) -> Result<StyledContent> { fn parse_styled_content(line: Value) -> Result<StyledContent> {
parse_array(line)?.iter().map(|tuple| { parse_array(line)?.into_iter().map(|tuple| {
if let [style_id, text] = parse_array(tuple)? { let [style_id, text] = extract_values(parse_array(tuple)?, [Value::Nil, Value::Nil])?;
Ok((parse_u64(style_id)?, parse_string(text)?.to_string()))
} else { Ok((parse_u64(style_id)?, parse_string(text)?))
Err(EventParseError::InvalidEventFormat)
}
}).collect() }).collect()
} }
fn parse_cmdline_show(cmdline_show_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cmdline_show(cmdline_show_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [content, position, first_character, prompt, indent, level] = cmdline_show_arguments { let values = [Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil, Value::Nil];
Ok(RedrawEvent::CommandLineShow { let [content, position, first_character, prompt, indent, level] = extract_values(cmdline_show_arguments, values)?;
content: parse_styled_content(content)?,
position: parse_u64(position)?, Ok(RedrawEvent::CommandLineShow {
first_character: parse_string(first_character)?.to_string(), content: parse_styled_content(content)?,
prompt: parse_string(prompt)?.to_string(), position: parse_u64(position)?,
indent: parse_u64(indent)?, first_character: parse_string(first_character)?,
level: parse_u64(level)? prompt: parse_string(prompt)?,
}) indent: parse_u64(indent)?,
} else { level: parse_u64(level)?
Err(EventParseError::InvalidEventFormat) })
}
} }
fn parse_cmdline_pos(cmdline_pos_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cmdline_pos(cmdline_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [position, level] = cmdline_pos_arguments { let [position, level] = extract_values(cmdline_pos_arguments, [Value::Nil, Value::Nil])?;
Ok(RedrawEvent::CommandLinePosition {
position: parse_u64(position)?, Ok(RedrawEvent::CommandLinePosition {
level: parse_u64(level)? position: parse_u64(position)?,
}) level: parse_u64(level)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_cmdline_special_char(cmdline_special_char_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cmdline_special_char(cmdline_special_char_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [character, shift, level] = cmdline_special_char_arguments { let [character, shift, level] = extract_values(cmdline_special_char_arguments, [Value::Nil, Value::Nil, Value::Nil])?;
Ok(RedrawEvent::CommandLineSpecialCharacter {
character: parse_string(character)?.to_string(), Ok(RedrawEvent::CommandLineSpecialCharacter {
shift: parse_bool(shift)?, character: parse_string(character)?,
level: parse_u64(level)? shift: parse_bool(shift)?,
}) level: parse_u64(level)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_cmdline_block_show(cmdline_block_show_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cmdline_block_show(cmdline_block_show_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [lines] = cmdline_block_show_arguments { let [lines] = extract_values(cmdline_block_show_arguments, [Value::Nil])?;
Ok(RedrawEvent::CommandLineBlockShow {
lines: parse_array(lines)? Ok(RedrawEvent::CommandLineBlockShow {
.iter() lines: parse_array(lines)?
.map(parse_styled_content) .into_iter()
.collect::<Result<_>>()? .map(parse_styled_content)
}) .collect::<Result<_>>()?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_cmdline_block_append(cmdline_block_append_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_cmdline_block_append(cmdline_block_append_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [line] = cmdline_block_append_arguments { let [line] = extract_values(cmdline_block_append_arguments, [Value::Nil])?;
Ok(RedrawEvent::CommandLineBlockAppend {
line: parse_styled_content(line)? Ok(RedrawEvent::CommandLineBlockAppend {
}) line: parse_styled_content(line)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_show(msg_show_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_show(msg_show_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [kind, content, replace_last] = msg_show_arguments { let [kind, content, replace_last] = extract_values(msg_show_arguments, [Value::Nil, Value::Nil, Value::Nil])?;
Ok(RedrawEvent::MessageShow {
kind: MessageKind::parse(parse_string(kind)?), Ok(RedrawEvent::MessageShow {
content: parse_styled_content(content)?, kind: MessageKind::parse(&parse_string(kind)?),
replace_last: parse_bool(replace_last)? content: parse_styled_content(content)?,
}) replace_last: parse_bool(replace_last)?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_showmode(msg_showmode_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_showmode(msg_showmode_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [content] = msg_showmode_arguments { let [content] = extract_values(msg_showmode_arguments, [Value::Nil])?;
Ok(RedrawEvent::MessageShowMode {
content: parse_styled_content(content)?, Ok(RedrawEvent::MessageShowMode {
}) content: parse_styled_content(content)?,
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_showcmd(msg_showcmd_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_showcmd(msg_showcmd_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [content] = msg_showcmd_arguments { let [content] = extract_values(msg_showcmd_arguments, [Value::Nil])?;
Ok(RedrawEvent::MessageShowCommand {
content: parse_styled_content(content)?, Ok(RedrawEvent::MessageShowCommand {
}) content: parse_styled_content(content)?,
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_ruler(msg_ruler_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_ruler(msg_ruler_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [content] = msg_ruler_arguments { let [content] = extract_values(msg_ruler_arguments, [Value::Nil])?;
Ok(RedrawEvent::MessageRuler {
content: parse_styled_content(content)?, Ok(RedrawEvent::MessageRuler {
}) content: parse_styled_content(content)?,
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_history_entry(entry: &Value) -> Result<(MessageKind, StyledContent)> { fn parse_msg_history_entry(entry: Value) -> Result<(MessageKind, StyledContent)> {
if let [kind, content] = parse_array(entry)?{ let [kind, content] = extract_values(parse_array(entry)?, [Value::Nil, Value::Nil])?;
Ok((
MessageKind::parse(parse_string(kind)?), Ok((
parse_styled_content(content)? MessageKind::parse(&parse_string(kind)?),
)) parse_styled_content(content)?
} else { ))
Err(EventParseError::InvalidEventFormat)
}
} }
fn parse_msg_history_show(msg_history_show_arguments: &[Value]) -> Result<RedrawEvent> { fn parse_msg_history_show(msg_history_show_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [entries] = msg_history_show_arguments { let [entries] = extract_values(msg_history_show_arguments, [Value::Nil])?;
Ok(RedrawEvent::MessageHistoryShow {
entries: parse_array(entries)? Ok(RedrawEvent::MessageHistoryShow {
.iter() entries: parse_array(entries)?
.map(parse_msg_history_entry) .into_iter()
.collect::<Result<_>>()? .map(parse_msg_history_entry)
}) .collect::<Result<_>>()?
} else { })
Err(EventParseError::InvalidEventFormat)
}
} }
pub fn parse_redraw_event(event_value: &Value) -> Result<Vec<RedrawEvent>> { pub fn parse_redraw_event(event_value: Value) -> Result<Vec<RedrawEvent>> {
let event_contents = parse_array(event_value)?; let mut event_contents = parse_array(event_value)?.into_iter();
let name_value = event_contents.get(0).ok_or(EventParseError::InvalidEventFormat)?; let event_name = event_contents.next()
let event_name = parse_string(name_value)?; .ok_or(EventParseError::InvalidEventFormat)
.and_then(parse_string)?;
let events = event_contents; let events = event_contents;
let mut parsed_events = Vec::with_capacity(events.len()); let mut parsed_events = Vec::with_capacity(events.len());
for event in &events[1..] { for event in events {
let event_parameters = parse_array(&event)?; let event_parameters = parse_array(event)?;
let possible_parsed_event = match event_name { let possible_parsed_event = match event_name.as_str() {
"set_title" => Some(parse_set_title(event_parameters)?), "set_title" => Some(parse_set_title(event_parameters)?),
"set_icon" => None, // Ignore set icon for now "set_icon" => None, // Ignore set icon for now
"mode_info_set" => Some(parse_mode_info_set(event_parameters)?), "mode_info_set" => Some(parse_mode_info_set(event_parameters)?),
@ -692,9 +649,10 @@ pub fn parse_redraw_event(event_value: &Value) -> Result<Vec<RedrawEvent>> {
Ok(parsed_events) Ok(parsed_events)
} }
pub(in super) fn parse_neovim_event(event_name: &str, arguments: &[Value]) -> Result<Vec<RedrawEvent>> { pub(in super) fn parse_neovim_event(event_name: &str, arguments: Vec<Value>) -> Result<Vec<RedrawEvent>> {
let mut resulting_events = Vec::with_capacity(arguments.len()); let mut resulting_events = Vec::new();
if event_name == "redraw" { if event_name == "redraw" {
resulting_events.reserve(arguments.len());
for event in arguments { for event in arguments {
resulting_events.append(&mut parse_redraw_event(event)?); resulting_events.append(&mut parse_redraw_event(event)?);
} }

@ -44,7 +44,7 @@ impl Handler for NeovimHandler {
async fn handle_notify(&self, event_name: String, arguments: Vec<Value>, _neovim: Neovim<Compat<ChildStdin>>) { async fn handle_notify(&self, event_name: String, arguments: Vec<Value>, _neovim: Neovim<Compat<ChildStdin>>) {
trace!("Neovim notification: {:?}", &event_name); trace!("Neovim notification: {:?}", &event_name);
let parsed_events = parse_neovim_event(&event_name, &arguments) let parsed_events = parse_neovim_event(&event_name, arguments)
.unwrap_or_explained_panic("Could not parse event from neovim"); .unwrap_or_explained_panic("Could not parse event from neovim");
for event in parsed_events { for event in parsed_events {
self.handle_redraw_event(event); self.handle_redraw_event(event);

Loading…
Cancel
Save