nu_protocol/ast/
unit.rs

1use crate::{Filesize, FilesizeUnit, IntoValue, ShellError, Span, Value};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub enum Unit {
6    Filesize(FilesizeUnit),
7
8    // Duration units
9    Nanosecond,
10    Microsecond,
11    Millisecond,
12    Second,
13    Minute,
14    Hour,
15    Day,
16    Week,
17}
18
19impl Unit {
20    pub fn build_value(self, size: i64, span: Span) -> Result<Value, ShellError> {
21        match self {
22            Unit::Filesize(unit) => {
23                if let Some(filesize) = Filesize::from_unit(size, unit) {
24                    Ok(filesize.into_value(span))
25                } else {
26                    Err(ShellError::GenericError {
27                        error: "filesize too large".into(),
28                        msg: "filesize too large".into(),
29                        span: Some(span),
30                        help: None,
31                        inner: vec![],
32                    })
33                }
34            }
35            Unit::Nanosecond => Ok(Value::duration(size, span)),
36            Unit::Microsecond => Ok(Value::duration(size * 1000, span)),
37            Unit::Millisecond => Ok(Value::duration(size * 1000 * 1000, span)),
38            Unit::Second => Ok(Value::duration(size * 1000 * 1000 * 1000, span)),
39            Unit::Minute => match size.checked_mul(1000 * 1000 * 1000 * 60) {
40                Some(val) => Ok(Value::duration(val, span)),
41                None => Err(ShellError::GenericError {
42                    error: "duration too large".into(),
43                    msg: "duration too large".into(),
44                    span: Some(span),
45                    help: None,
46                    inner: vec![],
47                }),
48            },
49            Unit::Hour => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60) {
50                Some(val) => Ok(Value::duration(val, span)),
51                None => Err(ShellError::GenericError {
52                    error: "duration too large".into(),
53                    msg: "duration too large".into(),
54                    span: Some(span),
55                    help: None,
56                    inner: vec![],
57                }),
58            },
59            Unit::Day => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24) {
60                Some(val) => Ok(Value::duration(val, span)),
61                None => Err(ShellError::GenericError {
62                    error: "duration too large".into(),
63                    msg: "duration too large".into(),
64                    span: Some(span),
65                    help: None,
66                    inner: vec![],
67                }),
68            },
69            Unit::Week => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24 * 7) {
70                Some(val) => Ok(Value::duration(val, span)),
71                None => Err(ShellError::GenericError {
72                    error: "duration too large".into(),
73                    msg: "duration too large".into(),
74                    span: Some(span),
75                    help: None,
76                    inner: vec![],
77                }),
78            },
79        }
80    }
81}