mirror of
https://github.com/nushell/nushell.git
synced 2024-12-25 08:29:07 +01:00
Implement IntoValue
for more types (#13744)
# Description Implements `IntoValue` for `&str` and `DateTime` as well as other nushell types like `Record` and `Closure`. Also allows `HashMap`s with keys besides `String` to implement `IntoValue`.
This commit is contained in:
parent
f4940e115f
commit
e3f59910b8
@ -377,7 +377,7 @@ fn file_completions_with_mixed_separators() {
|
||||
file(dir.join("lib-dir1").join("baz.nu")),
|
||||
file(dir.join("lib-dir1").join("xyzzy.nu")),
|
||||
];
|
||||
let expecetd_slash_paths: Vec<String> = expected_paths
|
||||
let expected_slash_paths: Vec<String> = expected_paths
|
||||
.iter()
|
||||
.map(|s| s.replace(MAIN_SEPARATOR, "/"))
|
||||
.collect();
|
||||
@ -385,22 +385,22 @@ fn file_completions_with_mixed_separators() {
|
||||
let target_dir = format!("ls {dir_str}/lib-dir1/");
|
||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||
|
||||
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||
match_suggestions(&expected_slash_paths, &suggestions);
|
||||
|
||||
let target_dir = format!("cp {dir_str}\\lib-dir1/");
|
||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||
|
||||
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||
match_suggestions(&expected_slash_paths, &suggestions);
|
||||
|
||||
let target_dir = format!("ls {dir_str}/lib-dir1\\/");
|
||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||
|
||||
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||
match_suggestions(&expected_slash_paths, &suggestions);
|
||||
|
||||
let target_dir = format!("ls {dir_str}\\lib-dir1\\/");
|
||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||
|
||||
match_suggestions(&expecetd_slash_paths, &suggestions);
|
||||
match_suggestions(&expected_slash_paths, &suggestions);
|
||||
|
||||
let target_dir = format!("ls {dir_str}\\lib-dir1\\");
|
||||
let suggestions = completer.complete(&target_dir, target_dir.len());
|
||||
|
@ -191,7 +191,7 @@ fn enum_into_value(
|
||||
.as_str()
|
||||
.to_case(container_attrs.rename_all.unwrap_or(Case::Snake));
|
||||
match &variant.fields {
|
||||
// In the future we can implement more complexe enums here.
|
||||
// In the future we can implement more complex enums here.
|
||||
Fields::Named(fields) => Err(DeriveError::UnsupportedEnums {
|
||||
fields_span: fields.span(),
|
||||
}),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{Record, ShellError, Span, Value};
|
||||
use crate::{ast::CellPath, engine::Closure, Range, Record, ShellError, Span, Value};
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
use std::{borrow::Borrow, collections::HashMap};
|
||||
|
||||
/// A trait for converting a value into a [`Value`].
|
||||
///
|
||||
@ -152,6 +152,12 @@ impl IntoValue for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for &str {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::string(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoValue for Vec<T>
|
||||
where
|
||||
T: IntoValue,
|
||||
@ -173,24 +179,59 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> IntoValue for HashMap<String, V>
|
||||
impl<K, V> IntoValue for HashMap<K, V>
|
||||
where
|
||||
K: Borrow<str> + Into<String>,
|
||||
V: IntoValue,
|
||||
{
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
let mut record = Record::new();
|
||||
for (k, v) in self.into_iter() {
|
||||
// Using `push` is fine as a hashmaps have unique keys.
|
||||
// To ensure this uniqueness, we only allow hashmaps with strings as
|
||||
// keys and not keys which implement `Into<String>` or `ToString`.
|
||||
record.push(k, v.into_value(span));
|
||||
}
|
||||
Value::record(record, span)
|
||||
// The `Borrow<str>` constraint is to ensure uniqueness, as implementations of `Borrow`
|
||||
// must uphold by certain properties (e.g., `(x == y) == (x.borrow() == y.borrow())`.
|
||||
//
|
||||
// The `Into<String>` constraint is necessary for us to convert the key into a `String`.
|
||||
// Most types that implement `Borrow<str>` also implement `Into<String>`.
|
||||
// Implementations of `Into` must also be lossless and value-preserving conversions.
|
||||
// So, when combined with the `Borrow` constraint, this means that the converted
|
||||
// `String` keys should be unique.
|
||||
self.into_iter()
|
||||
.map(|(k, v)| (k.into(), v.into_value(span)))
|
||||
.collect::<Record>()
|
||||
.into_value(span)
|
||||
}
|
||||
}
|
||||
|
||||
// Nu Types
|
||||
|
||||
impl IntoValue for Range {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::range(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for Record {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::record(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for Closure {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::closure(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for ShellError {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::error(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for CellPath {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::cell_path(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for Value {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
self.with_span(span)
|
||||
@ -199,6 +240,12 @@ impl IntoValue for Value {
|
||||
|
||||
// Foreign Types
|
||||
|
||||
impl IntoValue for DateTime<FixedOffset> {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::date(self, span)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoValue for bytes::Bytes {
|
||||
fn into_value(self, span: Span) -> Value {
|
||||
Value::binary(self.to_vec(), span)
|
||||
|
Loading…
Reference in New Issue
Block a user