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}