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