pub trait FromValue: Sized {
// Required method
fn from_value(v: Value) -> Result<Self, ShellError>;
// Provided method
fn expected_type() -> Type { ... }
}
Expand description
A trait for loading a value from a Value
.
§Derivable
This trait can be used with #[derive]
.
When derived on structs with named fields, it expects a Value::Record
where each field of
the struct maps to a corresponding field in the record.
- If
#[nu_value(rename = "...")]
is applied to a field, that name will be used as the key in the record. - If
#[nu_value(rename_all = "...")]
is applied on the container (struct) the key of the field will be case-converted accordingly. - If neither attribute is applied, the field name is used as is.
Supported case conversions include those provided by heck
, such as
“snake_case”, “kebab-case”, “PascalCase”, and others.
Additionally, all values accepted by
#[serde(rename_all = "...")]
are valid here.
For structs with unnamed fields, it expects a Value::List
, and the fields are populated in
the order they appear in the list.
Unit structs expect a Value::Nothing
, as they contain no data.
Attempting to convert from a non-matching Value
type will result in an error.
Only enums with no fields may derive this trait.
The expected value representation will be the name of the variant as a Value::String
.
- If
#[nu_value(rename = "...")]
is applied to a variant, that name will be used. - If
#[nu_value(rename_all = "...")]
is applied on the enum container, the name of variant will be case-converted accordingly. - If neither attribute is applied, the variant name will default to “snake_case”.
Additionally, you can use #[nu_value(type_name = "...")]
in the derive macro to set a custom type name
for FromValue::expected_type
. This will result in a Type::Custom
with the specified type name.
This can be useful in situations where the default type name is not desired.
§Enum Example
#[derive(FromValue, Debug, PartialEq)]
#[nu_value(rename_all = "COBOL-CASE", type_name = "birb")]
enum Bird {
MountainEagle,
ForestOwl,
#[nu_value(rename = "RIVER-QUACK")]
RiverDuck,
}
assert_eq!(
Bird::from_value(Value::string("FOREST-OWL", span)).unwrap(),
Bird::ForestOwl
);
assert_eq!(
Bird::from_value(Value::string("RIVER-QUACK", span)).unwrap(),
Bird::RiverDuck
);
assert_eq!(
&Bird::expected_type().to_string(),
"birb"
);
§Struct Example
#[derive(FromValue, PartialEq, Eq, Debug)]
#[nu_value(rename_all = "kebab-case")]
struct Person {
first_name: String,
last_name: String,
#[nu_value(rename = "age")]
age_years: u32,
}
let value = Value::record(record! {
"first-name" => Value::string("John", span),
"last-name" => Value::string("Doe", span),
"age" => Value::int(42, span),
}, span);
assert_eq!(
Person::from_value(value).unwrap(),
Person {
first_name: "John".into(),
last_name: "Doe".into(),
age_years: 42,
}
);
Required Methods§
Sourcefn from_value(v: Value) -> Result<Self, ShellError>
fn from_value(v: Value) -> Result<Self, ShellError>
Provided Methods§
Sourcefn expected_type() -> Type
fn expected_type() -> Type
Expected Value
type.
This is used to print out errors of what type of value is expected for conversion.
Even if not used in from_value
this should still be implemented
so that other implementations like Option
or Vec
can make use of it.
It is advised to call this method in from_value
to ensure that expected type in the error
is consistent.
Unlike the default implementation, derived implementations explicitly reveal the concrete
type, such as Type::Record
or Type::List
, instead of an opaque type.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.