nu_protocol/value/
custom_value.rs

1use std::{cmp::Ordering, fmt};
2
3use crate::{ShellError, Span, Type, Value, ast::Operator};
4
5/// Trait definition for a custom [`Value`](crate::Value) type
6#[typetag::serde(tag = "type")]
7pub trait CustomValue: fmt::Debug + Send + Sync {
8    /// Custom `Clone` implementation
9    ///
10    /// This can reemit a `Value::CustomValue(Self, span)` or materialize another representation
11    /// if necessary.
12    fn clone_value(&self, span: Span) -> Value;
13
14    //fn category(&self) -> Category;
15
16    /// The friendly type name to show for the custom value, e.g. in `describe` and in error
17    /// messages. This does not have to be the same as the name of the struct or enum, but
18    /// conventionally often is.
19    fn type_name(&self) -> String;
20
21    /// Converts the custom value to a base nushell value.
22    ///
23    /// This imposes the requirement that you can represent the custom value in some form using the
24    /// Value representations that already exist in nushell
25    fn to_base_value(&self, span: Span) -> Result<Value, ShellError>;
26
27    /// Any representation used to downcast object to its original type
28    fn as_any(&self) -> &dyn std::any::Any;
29
30    /// Any representation used to downcast object to its original type (mutable reference)
31    fn as_mut_any(&mut self) -> &mut dyn std::any::Any;
32
33    /// Follow cell path by numeric index (e.g. rows)
34    fn follow_path_int(
35        &self,
36        self_span: Span,
37        index: usize,
38        path_span: Span,
39    ) -> Result<Value, ShellError> {
40        let _ = (self_span, index);
41        Err(ShellError::IncompatiblePathAccess {
42            type_name: self.type_name(),
43            span: path_span,
44        })
45    }
46
47    /// Follow cell path by string key (e.g. columns)
48    fn follow_path_string(
49        &self,
50        self_span: Span,
51        column_name: String,
52        path_span: Span,
53    ) -> Result<Value, ShellError> {
54        let _ = (self_span, column_name);
55        Err(ShellError::IncompatiblePathAccess {
56            type_name: self.type_name(),
57            span: path_span,
58        })
59    }
60
61    /// ordering with other value (see [`std::cmp::PartialOrd`])
62    fn partial_cmp(&self, _other: &Value) -> Option<Ordering> {
63        None
64    }
65
66    /// Definition of an operation between the object that implements the trait
67    /// and another Value.
68    ///
69    /// The Operator enum is used to indicate the expected operation.
70    ///
71    /// Default impl raises [`ShellError::OperatorUnsupportedType`].
72    fn operation(
73        &self,
74        lhs_span: Span,
75        operator: Operator,
76        op: Span,
77        right: &Value,
78    ) -> Result<Value, ShellError> {
79        let _ = (lhs_span, right);
80        Err(ShellError::OperatorUnsupportedType {
81            op: operator,
82            unsupported: Type::Custom(self.type_name().into()),
83            op_span: op,
84            unsupported_span: lhs_span,
85            help: None,
86        })
87    }
88
89    /// For custom values in plugins: return `true` here if you would like to be notified when all
90    /// copies of this custom value are dropped in the engine.
91    ///
92    /// The notification will take place via `custom_value_dropped()` on the plugin type.
93    ///
94    /// The default is `false`.
95    fn notify_plugin_on_drop(&self) -> bool {
96        false
97    }
98}