nu_command/date/
humanize.rs1use crate::date::utils::parse_date_from_string;
2use chrono::{DateTime, FixedOffset, Local};
3use nu_engine::command_prelude::*;
4
5#[derive(Clone)]
6pub struct DateHumanize;
7
8impl Command for DateHumanize {
9 fn name(&self) -> &str {
10 "date humanize"
11 }
12
13 fn signature(&self) -> Signature {
14 Signature::build("date humanize")
15 .input_output_types(vec![
16 (Type::Date, Type::String),
17 (Type::String, Type::String),
18 ])
19 .allow_variants_without_examples(true)
20 .category(Category::Date)
21 }
22
23 fn description(&self) -> &str {
24 "Print a 'humanized' format for the date, relative to now."
25 }
26
27 fn search_terms(&self) -> Vec<&str> {
28 vec![
29 "relative",
30 "now",
31 "today",
32 "tomorrow",
33 "yesterday",
34 "weekday",
35 "weekday_name",
36 "timezone",
37 ]
38 }
39
40 fn run(
41 &self,
42 engine_state: &EngineState,
43 _stack: &mut Stack,
44 call: &Call,
45 input: PipelineData,
46 ) -> Result<PipelineData, ShellError> {
47 let head = call.head;
48 if let PipelineData::Empty = input {
50 return Err(ShellError::PipelineEmpty { dst_span: head });
51 }
52 input.map(move |value| helper(value, head), engine_state.signals())
53 }
54
55 fn examples(&self) -> Vec<Example<'_>> {
56 vec![Example {
57 description: "Print a 'humanized' format for the date, relative to now.",
58 example: r#""2021-10-22 20:00:12 +01:00" | date humanize"#,
59 result: None,
60 }]
61 }
62}
63
64fn helper(value: Value, head: Span) -> Value {
65 let span = value.span();
66 match value {
67 Value::Nothing { .. } => {
68 let dt = Local::now();
69 Value::string(humanize_date(dt.with_timezone(dt.offset())), head)
70 }
71 Value::String { val, .. } => {
72 let dt = parse_date_from_string(&val, span);
73 match dt {
74 Ok(x) => Value::string(humanize_date(x), head),
75 Err(e) => e,
76 }
77 }
78 Value::Date { val, .. } => Value::string(humanize_date(val), head),
79 _ => Value::error(
80 ShellError::OnlySupportsThisInputType {
81 exp_input_type: "date, string (that represents datetime), or nothing".into(),
82 wrong_type: value.get_type().to_string(),
83 dst_span: head,
84 src_span: span,
85 },
86 head,
87 ),
88 }
89}
90
91fn humanize_date(dt: DateTime<FixedOffset>) -> String {
92 nu_protocol::human_time_from_now(&dt).to_string()
93}
94
95#[cfg(test)]
96mod test {
97 use super::*;
98
99 #[test]
100 fn test_examples() {
101 use crate::test_examples;
102
103 test_examples(DateHumanize {})
104 }
105}