mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
Add string to datetime to str plugin (#1381)
* Add string to datetime to str plugin * Test string to date/time conversion
This commit is contained in:
parent
84927d52b5
commit
0961da406d
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2555,6 +2555,7 @@ dependencies = [
|
||||
name = "nu_plugin_str"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"nu-build",
|
||||
"nu-errors",
|
||||
"nu-plugin",
|
||||
|
@ -15,6 +15,7 @@ use crate::value::primitive::Primitive;
|
||||
use crate::value::range::{Range, RangeInclusion};
|
||||
use crate::{ColumnPath, PathMember};
|
||||
use bigdecimal::BigDecimal;
|
||||
use chrono::{DateTime, Utc};
|
||||
use indexmap::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_source::{AnchorLocation, HasSpan, Span, Spanned, Tag};
|
||||
@ -201,6 +202,10 @@ impl UntaggedValue {
|
||||
UntaggedValue::Primitive(Primitive::Date(s.into()))
|
||||
}
|
||||
|
||||
pub fn date(d: impl Into<DateTime<Utc>>) -> UntaggedValue {
|
||||
UntaggedValue::Primitive(Primitive::Date(d.into()))
|
||||
}
|
||||
|
||||
/// Helper for creating the Nothing value
|
||||
pub fn nothing() -> UntaggedValue {
|
||||
UntaggedValue::Primitive(Primitive::Nothing)
|
||||
|
@ -15,6 +15,7 @@ nu-protocol = { path = "../nu-protocol", version = "0.9.0" }
|
||||
nu-source = { path = "../nu-source", version = "0.9.0" }
|
||||
nu-errors = { path = "../nu-errors", version = "0.9.0" }
|
||||
nu-value-ext = { path = "../nu-value-ext", version = "0.9.0" }
|
||||
chrono = { version = "0.4.10", features = ["serde"] }
|
||||
|
||||
regex = "1"
|
||||
num-bigint = "0.2.3"
|
||||
|
@ -36,6 +36,12 @@ impl Plugin for Str {
|
||||
"convert string to portion of original, requires \"start,end\"",
|
||||
Some('s'),
|
||||
)
|
||||
.named(
|
||||
"to-date-time",
|
||||
SyntaxShape::String,
|
||||
"Convert string to Date/Time",
|
||||
Some('D'),
|
||||
)
|
||||
.rest(SyntaxShape::ColumnPath, "the column(s) to convert")
|
||||
.filter())
|
||||
}
|
||||
@ -117,6 +123,11 @@ impl Plugin for Str {
|
||||
self.for_field(possible_field);
|
||||
}
|
||||
|
||||
if let Some(dt) = args.get("to-date-time") {
|
||||
let dt = dt.as_string()?;
|
||||
self.for_date_time(dt);
|
||||
}
|
||||
|
||||
match &self.error {
|
||||
Some(reason) => Err(ShellError::untagged_runtime_error(format!(
|
||||
"{}: {}",
|
||||
|
@ -7,7 +7,37 @@ mod integration {
|
||||
unstructured_sample_record,
|
||||
};
|
||||
use nu_plugin::test_helpers::{expect_return_value_at, plugin, CallStub};
|
||||
use nu_protocol::UntaggedValue;
|
||||
use nu_protocol::{Primitive, UntaggedValue};
|
||||
|
||||
#[test]
|
||||
fn picks_up_date_time() {
|
||||
let run = plugin(&mut Str::new())
|
||||
.args(
|
||||
CallStub::new()
|
||||
.with_named_parameter("to-date-time", string("%d.%m.%Y %H:%M %P %z"))
|
||||
.create(),
|
||||
)
|
||||
.input(string("5.8.1994 8:00 am +0000"))
|
||||
.input(string("6.9.1995 10:00 am +0000"))
|
||||
.input(string("5.8.1994 20:00 pm +0000"))
|
||||
.input(string("20.4.2020 8:00 am +0000"))
|
||||
.setup(|_, _| {})
|
||||
.test();
|
||||
let ret_vals = run.unwrap();
|
||||
for r in ret_vals {
|
||||
let r = r
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.raw_value()
|
||||
.unwrap()
|
||||
.as_primitive()
|
||||
.unwrap();
|
||||
match r {
|
||||
Primitive::Date(_) => (),
|
||||
_ => assert!(false, "failed to convert string to date"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_up_one_action_flag_only() {
|
||||
|
@ -1,3 +1,6 @@
|
||||
extern crate chrono;
|
||||
|
||||
use chrono::DateTime;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{did_you_mean, ColumnPath, Primitive, ShellTypeName, UntaggedValue, Value};
|
||||
use nu_source::{span_for_spanned_list, Tagged};
|
||||
@ -12,6 +15,7 @@ pub enum Action {
|
||||
ToInteger,
|
||||
Substring(usize, usize),
|
||||
Replace(ReplaceAction),
|
||||
ToDateTime(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
@ -70,6 +74,10 @@ impl Str {
|
||||
Err(_) => UntaggedValue::string(input),
|
||||
},
|
||||
},
|
||||
Some(Action::ToDateTime(dt)) => match DateTime::parse_from_str(input, dt) {
|
||||
Ok(d) => UntaggedValue::date(d),
|
||||
Err(_) => UntaggedValue::string(input),
|
||||
},
|
||||
None => UntaggedValue::string(input),
|
||||
};
|
||||
|
||||
@ -89,27 +97,15 @@ impl Str {
|
||||
}
|
||||
|
||||
pub fn for_to_int(&mut self) {
|
||||
if self.permit() {
|
||||
self.action = Some(Action::ToInteger);
|
||||
} else {
|
||||
self.log_error("can only apply one");
|
||||
}
|
||||
self.add_action(Action::ToInteger);
|
||||
}
|
||||
|
||||
pub fn for_downcase(&mut self) {
|
||||
if self.permit() {
|
||||
self.action = Some(Action::Downcase);
|
||||
} else {
|
||||
self.log_error("can only apply one");
|
||||
}
|
||||
self.add_action(Action::Downcase);
|
||||
}
|
||||
|
||||
pub fn for_upcase(&mut self) {
|
||||
if self.permit() {
|
||||
self.action = Some(Action::Upcase);
|
||||
} else {
|
||||
self.log_error("can only apply one");
|
||||
}
|
||||
self.add_action(Action::Upcase);
|
||||
}
|
||||
|
||||
pub fn for_substring(&mut self, s: String) -> Result<(), ShellError> {
|
||||
@ -130,18 +126,24 @@ impl Str {
|
||||
};
|
||||
if start > end {
|
||||
self.log_error("End must be greater than or equal to Start");
|
||||
} else if self.permit() {
|
||||
self.action = Some(Action::Substring(start, end));
|
||||
} else {
|
||||
self.log_error("can only apply one");
|
||||
self.add_action(Action::Substring(start, end));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn for_replace(&mut self, mode: ReplaceAction) {
|
||||
self.add_action(Action::Replace(mode));
|
||||
}
|
||||
|
||||
pub fn for_date_time(&mut self, dt: String) {
|
||||
self.add_action(Action::ToDateTime(dt));
|
||||
}
|
||||
|
||||
fn add_action(&mut self, act: Action) {
|
||||
if self.permit() {
|
||||
self.action = Some(Action::Replace(mode));
|
||||
self.action = Some(act);
|
||||
} else {
|
||||
self.log_error("can only apply one");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user