use std::cmp::Ordering; use nu_protocol::{CustomValue, ShellError, Span, Value}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct SecondCustomValue { pub(crate) something: String, } impl SecondCustomValue { pub fn new(content: &str) -> Self { Self { something: content.to_owned(), } } pub fn into_value(self, span: Span) -> Value { Value::custom(Box::new(self), span) } pub fn try_from_value(value: &Value) -> Result { let span = value.span(); match value { Value::Custom { val, .. } => match val.as_any().downcast_ref::() { Some(value) => Ok(value.clone()), None => Err(ShellError::CantConvert { to_type: "cool".into(), from_type: "non-cool".into(), span, help: None, }), }, x => Err(ShellError::CantConvert { to_type: "cool".into(), from_type: x.get_type().to_string(), span, help: None, }), } } } #[typetag::serde] impl CustomValue for SecondCustomValue { fn clone_value(&self, span: nu_protocol::Span) -> Value { Value::custom(Box::new(self.clone()), span) } fn type_name(&self) -> String { self.typetag_name().to_string() } fn to_base_value(&self, span: nu_protocol::Span) -> Result { Ok(Value::string( format!( "I used to be a DIFFERENT custom value! ({})", self.something ), span, )) } fn partial_cmp(&self, other: &Value) -> Option { if let Value::Custom { val, .. } = other { val.as_any() .downcast_ref() .and_then(|other: &SecondCustomValue| PartialOrd::partial_cmp(self, other)) } else { None } } fn as_any(&self) -> &dyn std::any::Any { self } fn as_mut_any(&mut self) -> &mut dyn std::any::Any { self } }