use std::path::PathBuf;
use oo_protocol::{CommandOp, Operation as ProtoOp, TerminalOp, WindowOp, WorkspaceOp};
use crate::operation::{NotificationLevel, Operation, PickerItem as OpPickerItem, StatusSlot};
use crate::prelude::*;
pub(crate) fn to_operation(op: ProtoOp) -> Result<Operation> {
match op {
ProtoOp::Window(WindowOp::ShowNotification { message, level }) => {
let lvl = match level.as_str() {
"warn" => NotificationLevel::Warn,
"error" => NotificationLevel::Error,
_ => NotificationLevel::Info,
};
Ok(Operation::ShowNotification {
message,
level: lvl,
})
}
ProtoOp::Window(WindowOp::UpdateStatusBar { text, slot }) => {
let s = match slot.as_deref() {
Some("left") => StatusSlot::Left,
Some("center") => StatusSlot::Center,
_ => StatusSlot::Right,
};
Ok(Operation::UpdateStatusBar { text, slot: s })
}
ProtoOp::Window(WindowOp::ShowPicker { title, items }) => {
let mapped = items
.into_iter()
.map(|i| OpPickerItem {
label: i.label,
value: i.value,
})
.collect();
Ok(Operation::ShowPicker {
title: title.unwrap_or_default(),
items: mapped,
})
}
ProtoOp::Workspace(WorkspaceOp::OpenFile { path }) => Ok(Operation::OpenFile {
path: PathBuf::from(path),
}),
ProtoOp::Terminal(TerminalOp::Create { command }) => {
Ok(Operation::CreateTerminal { command })
}
ProtoOp::Command(CommandOp::Run { id }) => {
let cmd_id = id
.parse::<crate::commands::CommandId>()
.map_err(|e| anyhow!("invalid command id {:?}: {}", id, e))?;
Ok(Operation::RunCommand {
id: cmd_id,
args: Default::default(),
})
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use oo_protocol::{Operation as ProtoOp, TerminalOp, WindowOp, WorkspaceOp};
#[test]
fn show_notification_info() {
let op = to_operation(ProtoOp::Window(WindowOp::ShowNotification {
message: "Build ok".into(),
level: "info".into(),
}))
.unwrap();
assert!(
matches!(op, Operation::ShowNotification { ref message, level: NotificationLevel::Info } if message == "Build ok")
);
}
#[test]
fn show_notification_warn() {
let op = to_operation(ProtoOp::Window(WindowOp::ShowNotification {
message: "Watch out".into(),
level: "warn".into(),
}))
.unwrap();
assert!(matches!(
op,
Operation::ShowNotification {
level: NotificationLevel::Warn,
..
}
));
}
#[test]
fn open_file_op() {
let op = to_operation(ProtoOp::Workspace(WorkspaceOp::OpenFile {
path: "/tmp/foo.rs".into(),
}))
.unwrap();
assert!(
matches!(op, Operation::OpenFile { ref path } if path.to_str() == Some("/tmp/foo.rs"))
);
}
#[test]
fn update_status_bar_right() {
let op = to_operation(ProtoOp::Window(WindowOp::UpdateStatusBar {
text: "✓ ok".into(),
slot: Some("right".into()),
}))
.unwrap();
assert!(matches!(
op,
Operation::UpdateStatusBar {
slot: StatusSlot::Right,
..
}
));
}
#[test]
fn create_terminal_op() {
let op = to_operation(ProtoOp::Terminal(TerminalOp::Create {
command: "cargo build".into(),
}))
.unwrap();
assert!(
matches!(op, Operation::CreateTerminal { ref command } if command == "cargo build")
);
}
}