mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 06:30:08 +02:00
Range
refactor (#12405)
# Description Currently, `Range` is a struct with a `from`, `to`, and `incr` field, which are all type `Value`. This PR changes `Range` to be an enum over `IntRange` and `FloatRange` for better type safety / stronger compile time guarantees. Fixes: #11778 Fixes: #11777 Fixes: #11776 Fixes: #11775 Fixes: #11774 Fixes: #11773 Fixes: #11769. # User-Facing Changes Hopefully none, besides bug fixes. Although, the `serde` representation might have changed.
This commit is contained in:
@ -6,10 +6,7 @@ use crate::{
|
||||
TestCustomValue,
|
||||
},
|
||||
};
|
||||
use nu_protocol::{
|
||||
ast::RangeInclusion, engine::Closure, record, CustomValue, IntoSpanned, Range, ShellError,
|
||||
Span, Value,
|
||||
};
|
||||
use nu_protocol::{engine::Closure, record, CustomValue, IntoSpanned, ShellError, Span, Value};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
@ -60,50 +57,6 @@ fn add_source_in_at_root() -> Result<(), ShellError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_range_custom_values(
|
||||
val: &Value,
|
||||
mut f: impl FnMut(&str, &dyn CustomValue) -> Result<(), ShellError>,
|
||||
) -> Result<(), ShellError> {
|
||||
let range = val.as_range()?;
|
||||
for (name, val) in [
|
||||
("from", &range.from),
|
||||
("incr", &range.incr),
|
||||
("to", &range.to),
|
||||
] {
|
||||
let custom_value = val
|
||||
.as_custom_value()
|
||||
.unwrap_or_else(|_| panic!("{name} not custom value"));
|
||||
f(name, custom_value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_source_in_nested_range() -> Result<(), ShellError> {
|
||||
let orig_custom_val = Value::test_custom_value(Box::new(test_plugin_custom_value()));
|
||||
let mut val = Value::test_range(Range {
|
||||
from: orig_custom_val.clone(),
|
||||
incr: orig_custom_val.clone(),
|
||||
to: orig_custom_val.clone(),
|
||||
inclusion: RangeInclusion::Inclusive,
|
||||
});
|
||||
let source = Arc::new(PluginSource::new_fake("foo"));
|
||||
PluginCustomValue::add_source_in(&mut val, &source)?;
|
||||
|
||||
check_range_custom_values(&val, |name, custom_value| {
|
||||
let plugin_custom_value: &PluginCustomValue = custom_value
|
||||
.as_any()
|
||||
.downcast_ref()
|
||||
.unwrap_or_else(|| panic!("{name} not PluginCustomValue"));
|
||||
assert_eq!(
|
||||
Some(Arc::as_ptr(&source)),
|
||||
plugin_custom_value.source.as_ref().map(Arc::as_ptr),
|
||||
"{name} source not set correctly"
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn check_record_custom_values(
|
||||
val: &Value,
|
||||
keys: &[&str],
|
||||
@ -292,31 +245,6 @@ fn serialize_in_root() -> Result<(), ShellError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_in_range() -> Result<(), ShellError> {
|
||||
let orig_custom_val = Value::test_custom_value(Box::new(TestCustomValue(-1)));
|
||||
let mut val = Value::test_range(Range {
|
||||
from: orig_custom_val.clone(),
|
||||
incr: orig_custom_val.clone(),
|
||||
to: orig_custom_val.clone(),
|
||||
inclusion: RangeInclusion::Inclusive,
|
||||
});
|
||||
PluginCustomValue::serialize_custom_values_in(&mut val)?;
|
||||
|
||||
check_range_custom_values(&val, |name, custom_value| {
|
||||
let plugin_custom_value: &PluginCustomValue = custom_value
|
||||
.as_any()
|
||||
.downcast_ref()
|
||||
.unwrap_or_else(|| panic!("{name} not PluginCustomValue"));
|
||||
assert_eq!(
|
||||
"TestCustomValue",
|
||||
plugin_custom_value.name(),
|
||||
"{name} name not set correctly"
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_in_record() -> Result<(), ShellError> {
|
||||
let orig_custom_val = Value::test_custom_value(Box::new(TestCustomValue(32)));
|
||||
@ -400,31 +328,6 @@ fn deserialize_in_root() -> Result<(), ShellError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_in_range() -> Result<(), ShellError> {
|
||||
let orig_custom_val = Value::test_custom_value(Box::new(test_plugin_custom_value()));
|
||||
let mut val = Value::test_range(Range {
|
||||
from: orig_custom_val.clone(),
|
||||
incr: orig_custom_val.clone(),
|
||||
to: orig_custom_val.clone(),
|
||||
inclusion: RangeInclusion::Inclusive,
|
||||
});
|
||||
PluginCustomValue::deserialize_custom_values_in(&mut val)?;
|
||||
|
||||
check_range_custom_values(&val, |name, custom_value| {
|
||||
let test_custom_value: &TestCustomValue = custom_value
|
||||
.as_any()
|
||||
.downcast_ref()
|
||||
.unwrap_or_else(|| panic!("{name} not TestCustomValue"));
|
||||
assert_eq!(
|
||||
expected_test_custom_value(),
|
||||
*test_custom_value,
|
||||
"{name} not deserialized correctly"
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_in_record() -> Result<(), ShellError> {
|
||||
let orig_custom_val = Value::test_custom_value(Box::new(test_plugin_custom_value()));
|
||||
|
@ -33,7 +33,7 @@ where
|
||||
#[test]
|
||||
fn find_custom_values() {
|
||||
use crate::protocol::test_util::test_plugin_custom_value;
|
||||
use nu_protocol::{ast::RangeInclusion, engine::Closure, record, LazyRecord, Range, Span};
|
||||
use nu_protocol::{engine::Closure, record, LazyRecord, Span};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Lazy;
|
||||
@ -73,12 +73,6 @@ fn find_custom_values() {
|
||||
captures: vec![(0, cv.clone()), (1, Value::test_string("foo"))]
|
||||
}
|
||||
),
|
||||
"range" => Value::test_range(Range {
|
||||
from: cv.clone(),
|
||||
incr: cv.clone(),
|
||||
to: cv.clone(),
|
||||
inclusion: RangeInclusion::Inclusive
|
||||
}),
|
||||
"lazy" => Value::test_lazy_record(Box::new(Lazy)),
|
||||
});
|
||||
|
||||
@ -89,7 +83,7 @@ fn find_custom_values() {
|
||||
Ok(())
|
||||
})
|
||||
.expect("error");
|
||||
assert_eq!(7, found, "found in value");
|
||||
assert_eq!(4, found, "found in value");
|
||||
|
||||
// Try it on bare custom value too
|
||||
found = 0;
|
||||
|
Reference in New Issue
Block a user