use crate::{value::Value, ConfigPath};
use nu_errors::ShellError;
use nu_source::{DbgDocBldr, DebugDocBuilder, PrettyDebug};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CommandAction {
ChangePath(String),
Exit(i32),
Error(ShellError),
EnterShell(String),
AutoConvert(Value, String),
EnterValueShell(Value),
AddPlugins(String),
UnloadConfig(ConfigPath),
LoadConfig(ConfigPath),
PreviousShell,
NextShell,
GotoShell(usize),
LeaveShell(i32),
}
impl PrettyDebug for CommandAction {
fn pretty(&self) -> DebugDocBuilder {
match self {
CommandAction::ChangePath(path) => {
DbgDocBldr::typed("change path", DbgDocBldr::description(path))
}
CommandAction::Exit(_) => DbgDocBldr::description("exit"),
CommandAction::Error(_) => DbgDocBldr::error("error"),
CommandAction::AutoConvert(_, extension) => {
DbgDocBldr::typed("auto convert", DbgDocBldr::description(extension))
}
CommandAction::EnterShell(s) => {
DbgDocBldr::typed("enter shell", DbgDocBldr::description(s))
}
CommandAction::EnterValueShell(v) => DbgDocBldr::typed("enter value shell", v.pretty()),
CommandAction::AddPlugins(..) => DbgDocBldr::description("add plugins"),
CommandAction::PreviousShell => DbgDocBldr::description("previous shell"),
CommandAction::NextShell => DbgDocBldr::description("next shell"),
CommandAction::GotoShell(_) => DbgDocBldr::description("goto shell"),
CommandAction::LeaveShell(_) => DbgDocBldr::description("leave shell"),
CommandAction::UnloadConfig(cfg) => {
DbgDocBldr::description(format!("unload config {:?}", cfg))
}
CommandAction::LoadConfig(cfg) => {
DbgDocBldr::description(format!("load config {:?}", cfg))
}
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ReturnSuccess {
Value(Value),
DebugValue(Value),
Action(CommandAction),
}
impl PrettyDebug for ReturnSuccess {
fn pretty(&self) -> DebugDocBuilder {
match self {
ReturnSuccess::Value(value) => DbgDocBldr::typed("value", value.pretty()),
ReturnSuccess::DebugValue(value) => DbgDocBldr::typed("debug value", value.pretty()),
ReturnSuccess::Action(action) => DbgDocBldr::typed("action", action.pretty()),
}
}
}
pub type ReturnValue = Result<ReturnSuccess, ShellError>;
impl From<Value> for ReturnValue {
fn from(v: Value) -> Self {
Ok(ReturnSuccess::Value(v))
}
}
impl ReturnSuccess {
pub fn raw_value(&self) -> Option<Value> {
match self {
ReturnSuccess::Value(raw) => Some(raw.clone()),
ReturnSuccess::DebugValue(raw) => Some(raw.clone()),
ReturnSuccess::Action(_) => None,
}
}
pub fn change_cwd(path: String) -> ReturnValue {
Ok(ReturnSuccess::Action(CommandAction::ChangePath(path)))
}
pub fn value(input: impl Into<Value>) -> ReturnValue {
Ok(ReturnSuccess::Value(input.into()))
}
pub fn debug_value(input: impl Into<Value>) -> ReturnValue {
Ok(ReturnSuccess::DebugValue(input.into()))
}
pub fn action(input: CommandAction) -> ReturnValue {
Ok(ReturnSuccess::Action(input))
}
}
#[cfg(test)]
mod tests {
use crate::{ReturnSuccess, ReturnValue, UntaggedValue};
#[test]
fn return_value_can_be_used_in_assert_eq() {
let v1: ReturnValue = ReturnSuccess::value(UntaggedValue::nothing());
let v2: ReturnValue = ReturnSuccess::value(UntaggedValue::nothing());
assert_eq!(v1, v2);
}
}