mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 09:53:43 +01:00
parent
b32eceffb3
commit
2956b0b087
@ -5,12 +5,16 @@ use nu_errors::ShellError;
|
|||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Associated information for the call of a command, including the args passed to the command and a tag that spans the name of the command being called
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
pub struct CallInfo {
|
pub struct CallInfo {
|
||||||
pub args: EvaluatedArgs,
|
pub args: EvaluatedArgs,
|
||||||
pub name_tag: Tag,
|
pub name_tag: Tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The set of positional and named arguments, after their values have been evaluated.
|
||||||
|
/// Positional arguments are those who are given as values, without any associated flag. For example, in `foo arg1 arg2`, both `arg1` and `arg2` are positional arguments
|
||||||
|
/// Named arguments are those associated with a flag. For example, `foo --given bar` the named argument would be name `given` and the value `bar`.
|
||||||
#[derive(Debug, Default, new, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, new, Serialize, Deserialize, Clone)]
|
||||||
pub struct EvaluatedArgs {
|
pub struct EvaluatedArgs {
|
||||||
pub positional: Option<Vec<Value>>,
|
pub positional: Option<Vec<Value>>,
|
||||||
@ -18,6 +22,7 @@ pub struct EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EvaluatedArgs {
|
impl EvaluatedArgs {
|
||||||
|
/// Retrieve a subset of positional arguments starting at a given position
|
||||||
pub fn slice_from(&self, from: usize) -> Vec<Value> {
|
pub fn slice_from(&self, from: usize) -> Vec<Value> {
|
||||||
let positional = &self.positional;
|
let positional = &self.positional;
|
||||||
|
|
||||||
@ -27,6 +32,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the nth positional argument, if possible
|
||||||
pub fn nth(&self, pos: usize) -> Option<&Value> {
|
pub fn nth(&self, pos: usize) -> Option<&Value> {
|
||||||
match &self.positional {
|
match &self.positional {
|
||||||
None => None,
|
None => None,
|
||||||
@ -34,6 +40,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the nth positional argument, error if not possible
|
||||||
pub fn expect_nth(&self, pos: usize) -> Result<&Value, ShellError> {
|
pub fn expect_nth(&self, pos: usize) -> Result<&Value, ShellError> {
|
||||||
match &self.positional {
|
match &self.positional {
|
||||||
None => Err(ShellError::unimplemented("Better error: expect_nth")),
|
None => Err(ShellError::unimplemented("Better error: expect_nth")),
|
||||||
@ -44,6 +51,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of positional arguments available
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
match &self.positional {
|
match &self.positional {
|
||||||
None => 0,
|
None => 0,
|
||||||
@ -51,10 +59,12 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return if there are no positional arguments
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if the set of named arguments contains the name provided
|
||||||
pub fn has(&self, name: &str) -> bool {
|
pub fn has(&self, name: &str) -> bool {
|
||||||
match &self.named {
|
match &self.named {
|
||||||
None => false,
|
None => false,
|
||||||
@ -62,6 +72,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the corresponding Value for the named argument given, if possible
|
||||||
pub fn get(&self, name: &str) -> Option<&Value> {
|
pub fn get(&self, name: &str) -> Option<&Value> {
|
||||||
match &self.named {
|
match &self.named {
|
||||||
None => None,
|
None => None,
|
||||||
@ -69,6 +80,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterates over the positional arguments
|
||||||
pub fn positional_iter(&self) -> PositionalIter<'_> {
|
pub fn positional_iter(&self) -> PositionalIter<'_> {
|
||||||
match &self.positional {
|
match &self.positional {
|
||||||
None => PositionalIter::Empty,
|
None => PositionalIter::Empty,
|
||||||
@ -80,6 +92,7 @@ impl EvaluatedArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator to help iterate over positional arguments
|
||||||
pub enum PositionalIter<'a> {
|
pub enum PositionalIter<'a> {
|
||||||
Empty,
|
Empty,
|
||||||
Array(std::slice::Iter<'a, Value>),
|
Array(std::slice::Iter<'a, Value>),
|
||||||
@ -88,6 +101,7 @@ pub enum PositionalIter<'a> {
|
|||||||
impl<'a> Iterator for PositionalIter<'a> {
|
impl<'a> Iterator for PositionalIter<'a> {
|
||||||
type Item = &'a Value;
|
type Item = &'a Value;
|
||||||
|
|
||||||
|
/// The required `next` function to implement the Iterator trait
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
match self {
|
match self {
|
||||||
PositionalIter::Empty => None,
|
PositionalIter::Empty => None,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![allow(clippy::should_implement_trait)]
|
#![allow(clippy::should_implement_trait)]
|
||||||
|
|
||||||
|
/// Helper type to allow passing something that may potentially be owned, but could also be borrowed
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MaybeOwned<'a, T> {
|
pub enum MaybeOwned<'a, T> {
|
||||||
Owned(T),
|
Owned(T),
|
||||||
@ -7,6 +8,7 @@ pub enum MaybeOwned<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MaybeOwned<'_, T> {
|
impl<T> MaybeOwned<'_, T> {
|
||||||
|
/// Allows the borrowing of an owned value or passes out the borrowed value
|
||||||
pub fn borrow(&self) -> &T {
|
pub fn borrow(&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
MaybeOwned::Owned(v) => v,
|
MaybeOwned::Owned(v) => v,
|
||||||
|
@ -3,21 +3,33 @@ use nu_errors::ShellError;
|
|||||||
use nu_source::{b, DebugDocBuilder, PrettyDebug};
|
use nu_source::{b, DebugDocBuilder, PrettyDebug};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// The inner set of actions for the command processor. Each denotes a way to change state in the processor without changing it directly from the command itself.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum CommandAction {
|
pub enum CommandAction {
|
||||||
|
/// Change to a new directory or path (in non-filesystem situations)
|
||||||
ChangePath(String),
|
ChangePath(String),
|
||||||
|
/// Exit out of Nu
|
||||||
Exit,
|
Exit,
|
||||||
|
/// Display an error
|
||||||
Error(ShellError),
|
Error(ShellError),
|
||||||
|
/// Enter a new shell at the given path
|
||||||
EnterShell(String),
|
EnterShell(String),
|
||||||
|
/// Convert the value given from one type to another
|
||||||
AutoConvert(Value, String),
|
AutoConvert(Value, String),
|
||||||
|
/// Enter a value shell, one that allows exploring inside of a Value
|
||||||
EnterValueShell(Value),
|
EnterValueShell(Value),
|
||||||
|
/// Enter the help shell, which allows exploring the help system
|
||||||
EnterHelpShell(Value),
|
EnterHelpShell(Value),
|
||||||
|
/// Go to the previous shell in the shell ring buffer
|
||||||
PreviousShell,
|
PreviousShell,
|
||||||
|
/// Go to the next shell in the shell ring buffer
|
||||||
NextShell,
|
NextShell,
|
||||||
|
/// Leave the current shell. If it's the last shell, exit out of Nu
|
||||||
LeaveShell,
|
LeaveShell,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyDebug for CommandAction {
|
impl PrettyDebug for CommandAction {
|
||||||
|
/// Get a command action ready to be pretty-printed
|
||||||
fn pretty(&self) -> DebugDocBuilder {
|
fn pretty(&self) -> DebugDocBuilder {
|
||||||
match self {
|
match self {
|
||||||
CommandAction::ChangePath(path) => b::typed("change path", b::description(path)),
|
CommandAction::ChangePath(path) => b::typed("change path", b::description(path)),
|
||||||
@ -36,14 +48,19 @@ impl PrettyDebug for CommandAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The fundamental success type in the pipeline. Commands return these values as their main responsibility
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum ReturnSuccess {
|
pub enum ReturnSuccess {
|
||||||
|
/// A value to be used or shown to the user
|
||||||
Value(Value),
|
Value(Value),
|
||||||
|
/// A debug-enabled value to be used or shown to the user
|
||||||
DebugValue(Value),
|
DebugValue(Value),
|
||||||
|
/// An action to be performed as values pass out of the command. These are performed rather than passed to the next command in the pipeline
|
||||||
Action(CommandAction),
|
Action(CommandAction),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyDebug for ReturnSuccess {
|
impl PrettyDebug for ReturnSuccess {
|
||||||
|
/// Get a return success ready to be pretty-printed
|
||||||
fn pretty(&self) -> DebugDocBuilder {
|
fn pretty(&self) -> DebugDocBuilder {
|
||||||
match self {
|
match self {
|
||||||
ReturnSuccess::Value(value) => b::typed("value", value.pretty()),
|
ReturnSuccess::Value(value) => b::typed("value", value.pretty()),
|
||||||
@ -53,15 +70,18 @@ impl PrettyDebug for ReturnSuccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The core Result type for pipelines
|
||||||
pub type ReturnValue = Result<ReturnSuccess, ShellError>;
|
pub type ReturnValue = Result<ReturnSuccess, ShellError>;
|
||||||
|
|
||||||
impl Into<ReturnValue> for Value {
|
impl Into<ReturnValue> for Value {
|
||||||
|
/// Lift a Value into a ReturnValue
|
||||||
fn into(self) -> ReturnValue {
|
fn into(self) -> ReturnValue {
|
||||||
Ok(ReturnSuccess::Value(self))
|
Ok(ReturnSuccess::Value(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReturnSuccess {
|
impl ReturnSuccess {
|
||||||
|
/// Get to the contained Value, if possible
|
||||||
pub fn raw_value(&self) -> Option<Value> {
|
pub fn raw_value(&self) -> Option<Value> {
|
||||||
match self {
|
match self {
|
||||||
ReturnSuccess::Value(raw) => Some(raw.clone()),
|
ReturnSuccess::Value(raw) => Some(raw.clone()),
|
||||||
@ -70,18 +90,22 @@ impl ReturnSuccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function for an action to change the the path
|
||||||
pub fn change_cwd(path: String) -> ReturnValue {
|
pub fn change_cwd(path: String) -> ReturnValue {
|
||||||
Ok(ReturnSuccess::Action(CommandAction::ChangePath(path)))
|
Ok(ReturnSuccess::Action(CommandAction::ChangePath(path)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function to create simple values for returning
|
||||||
pub fn value(input: impl Into<Value>) -> ReturnValue {
|
pub fn value(input: impl Into<Value>) -> ReturnValue {
|
||||||
Ok(ReturnSuccess::Value(input.into()))
|
Ok(ReturnSuccess::Value(input.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function to create simple debug-enabled values for returning
|
||||||
pub fn debug_value(input: impl Into<Value>) -> ReturnValue {
|
pub fn debug_value(input: impl Into<Value>) -> ReturnValue {
|
||||||
Ok(ReturnSuccess::DebugValue(input.into()))
|
Ok(ReturnSuccess::DebugValue(input.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function for creating actions
|
||||||
pub fn action(input: CommandAction) -> ReturnValue {
|
pub fn action(input: CommandAction) -> ReturnValue {
|
||||||
Ok(ReturnSuccess::Action(input))
|
Ok(ReturnSuccess::Action(input))
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,7 @@ impl TaggedDictBuilder {
|
|||||||
builder.into_value()
|
builder.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new builder with a pre-defined capacity
|
||||||
pub fn with_capacity(tag: impl Into<Tag>, n: usize) -> TaggedDictBuilder {
|
pub fn with_capacity(tag: impl Into<Tag>, n: usize) -> TaggedDictBuilder {
|
||||||
TaggedDictBuilder {
|
TaggedDictBuilder {
|
||||||
tag: tag.into(),
|
tag: tag.into(),
|
||||||
@ -194,30 +195,36 @@ impl TaggedDictBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert an untagged key/value pair into the dictionary, to later be tagged when built
|
||||||
pub fn insert_untagged(&mut self, key: impl Into<String>, value: impl Into<UntaggedValue>) {
|
pub fn insert_untagged(&mut self, key: impl Into<String>, value: impl Into<UntaggedValue>) {
|
||||||
self.dict
|
self.dict
|
||||||
.insert(key.into(), value.into().into_value(&self.tag));
|
.insert(key.into(), value.into().into_value(&self.tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert a key/value pair into the dictionary
|
||||||
pub fn insert_value(&mut self, key: impl Into<String>, value: impl Into<Value>) {
|
pub fn insert_value(&mut self, key: impl Into<String>, value: impl Into<Value>) {
|
||||||
self.dict.insert(key.into(), value.into());
|
self.dict.insert(key.into(), value.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the dictionary into a tagged Value using the original tag
|
||||||
pub fn into_value(self) -> Value {
|
pub fn into_value(self) -> Value {
|
||||||
let tag = self.tag.clone();
|
let tag = self.tag.clone();
|
||||||
self.into_untagged_value().into_value(tag)
|
self.into_untagged_value().into_value(tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the dictionary into an UntaggedValue
|
||||||
pub fn into_untagged_value(self) -> UntaggedValue {
|
pub fn into_untagged_value(self) -> UntaggedValue {
|
||||||
UntaggedValue::Row(Dictionary { entries: self.dict })
|
UntaggedValue::Row(Dictionary { entries: self.dict })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the dictionary is empty, false otherwise
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.dict.is_empty()
|
self.dict.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TaggedDictBuilder> for Value {
|
impl From<TaggedDictBuilder> for Value {
|
||||||
|
/// Convert a builder into a tagged Value
|
||||||
fn from(input: TaggedDictBuilder) -> Value {
|
fn from(input: TaggedDictBuilder) -> Value {
|
||||||
input.into_value()
|
input.into_value()
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::cmp::{Ord, Ordering, PartialOrd};
|
use std::cmp::{Ord, Ordering, PartialOrd};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
/// An evaluation scope. Scopes map variable names to Values and aid in evaluating blocks and expressions.
|
||||||
|
/// Additionally, holds the value for the special $it variable, a variable used to refer to the value passing
|
||||||
|
/// through the pipeline at that moment
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
pub it: Value,
|
pub it: Value,
|
||||||
@ -13,6 +16,7 @@ pub struct Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
|
/// Create a new scope
|
||||||
pub fn new(it: Value) -> Scope {
|
pub fn new(it: Value) -> Scope {
|
||||||
Scope {
|
Scope {
|
||||||
it,
|
it,
|
||||||
@ -22,6 +26,7 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
|
/// Create an empty scope
|
||||||
pub fn empty() -> Scope {
|
pub fn empty() -> Scope {
|
||||||
Scope {
|
Scope {
|
||||||
it: UntaggedValue::Primitive(Primitive::Nothing).into_untagged_value(),
|
it: UntaggedValue::Primitive(Primitive::Nothing).into_untagged_value(),
|
||||||
@ -29,6 +34,7 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an empty scope, setting $it to a known Value
|
||||||
pub fn it_value(value: Value) -> Scope {
|
pub fn it_value(value: Value) -> Scope {
|
||||||
Scope {
|
Scope {
|
||||||
it: value,
|
it: value,
|
||||||
|
@ -11,32 +11,52 @@ use num_traits::cast::{FromPrimitive, ToPrimitive};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// The most fundamental of structured values in Nu are the Primitive values. These values represent types like integers, strings, booleans, dates, etc that are then used
|
||||||
|
/// as the buildig blocks to build up more complex structures.
|
||||||
|
///
|
||||||
|
/// Primitives also include marker values BeginningOfStream and EndOfStream which denote a change of condition in the stream
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Deserialize, Serialize)]
|
||||||
pub enum Primitive {
|
pub enum Primitive {
|
||||||
|
/// An empty value
|
||||||
Nothing,
|
Nothing,
|
||||||
|
/// A "big int", an integer with arbitrarily large size (aka not limited to 64-bit)
|
||||||
#[serde(with = "serde_bigint")]
|
#[serde(with = "serde_bigint")]
|
||||||
Int(BigInt),
|
Int(BigInt),
|
||||||
|
/// A "big decimal", an decimal number with arbitrarily large size (aka not limited to 64-bit)
|
||||||
#[serde(with = "serde_bigdecimal")]
|
#[serde(with = "serde_bigdecimal")]
|
||||||
Decimal(BigDecimal),
|
Decimal(BigDecimal),
|
||||||
|
/// A count in the number of bytes, used as a filesize
|
||||||
Bytes(u64),
|
Bytes(u64),
|
||||||
|
/// A string value
|
||||||
String(String),
|
String(String),
|
||||||
|
/// A string value with an implied carriage return (or cr/lf) ending
|
||||||
Line(String),
|
Line(String),
|
||||||
|
/// A path to travel to reach a value in a table
|
||||||
ColumnPath(ColumnPath),
|
ColumnPath(ColumnPath),
|
||||||
|
/// A glob pattern, eg foo*
|
||||||
Pattern(String),
|
Pattern(String),
|
||||||
|
/// A boolean value
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
|
/// A date value, in UTC
|
||||||
Date(DateTime<Utc>),
|
Date(DateTime<Utc>),
|
||||||
Duration(u64), // Duration in seconds
|
/// A count in the number of seconds
|
||||||
|
Duration(u64),
|
||||||
|
/// A range of values
|
||||||
Range(Box<Range>),
|
Range(Box<Range>),
|
||||||
|
/// A file path
|
||||||
Path(PathBuf),
|
Path(PathBuf),
|
||||||
|
/// A vector of raw binary data
|
||||||
#[serde(with = "serde_bytes")]
|
#[serde(with = "serde_bytes")]
|
||||||
Binary(Vec<u8>),
|
Binary(Vec<u8>),
|
||||||
|
|
||||||
// Stream markers (used as bookend markers rather than actual values)
|
/// Beginning of stream marker, a pseudo-value not intended for tables
|
||||||
BeginningOfStream,
|
BeginningOfStream,
|
||||||
|
/// End of stream marker, a pseudo-value not intended for tables
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Primitive {
|
impl Primitive {
|
||||||
|
/// Converts a primitive value to a u64, if possible. Uses a span to build an error if the conversion isn't possible.
|
||||||
pub fn as_u64(&self, span: Span) -> Result<u64, ShellError> {
|
pub fn as_u64(&self, span: Span) -> Result<u64, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
Primitive::Int(int) => match int.to_u64() {
|
Primitive::Int(int) => match int.to_u64() {
|
||||||
@ -56,12 +76,14 @@ impl Primitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<BigDecimal> for Primitive {
|
impl From<BigDecimal> for Primitive {
|
||||||
|
/// Helper to convert from decimals to a Primitive value
|
||||||
fn from(decimal: BigDecimal) -> Primitive {
|
fn from(decimal: BigDecimal) -> Primitive {
|
||||||
Primitive::Decimal(decimal)
|
Primitive::Decimal(decimal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f64> for Primitive {
|
impl From<f64> for Primitive {
|
||||||
|
/// Helper to convert from 64-bit float to a Primitive value
|
||||||
fn from(float: f64) -> Primitive {
|
fn from(float: f64) -> Primitive {
|
||||||
if let Some(f) = BigDecimal::from_f64(float) {
|
if let Some(f) = BigDecimal::from_f64(float) {
|
||||||
Primitive::Decimal(f)
|
Primitive::Decimal(f)
|
||||||
@ -72,6 +94,7 @@ impl From<f64> for Primitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ShellTypeName for Primitive {
|
impl ShellTypeName for Primitive {
|
||||||
|
/// Get the name of the type of a Primitive value
|
||||||
fn type_name(&self) -> &'static str {
|
fn type_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Primitive::Nothing => "nothing",
|
Primitive::Nothing => "nothing",
|
||||||
@ -94,6 +117,7 @@ impl ShellTypeName for Primitive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Format a Primitive value into a string
|
||||||
pub fn format_primitive(primitive: &Primitive, field_name: Option<&String>) -> String {
|
pub fn format_primitive(primitive: &Primitive, field_name: Option<&String>) -> String {
|
||||||
match primitive {
|
match primitive {
|
||||||
Primitive::Nothing => String::new(),
|
Primitive::Nothing => String::new(),
|
||||||
@ -157,6 +181,7 @@ pub fn format_primitive(primitive: &Primitive, field_name: Option<&String>) -> S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Format a duration in seconds into a string
|
||||||
pub fn format_duration(sec: u64) -> String {
|
pub fn format_duration(sec: u64) -> String {
|
||||||
let (minutes, seconds) = (sec / 60, sec % 60);
|
let (minutes, seconds) = (sec / 60, sec % 60);
|
||||||
let (hours, minutes) = (minutes / 60, minutes % 60);
|
let (hours, minutes) = (minutes / 60, minutes % 60);
|
||||||
@ -171,6 +196,7 @@ pub fn format_duration(sec: u64) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Format a UTC date value into a humanized string (eg "1 week ago" instead of a formal date string)
|
||||||
pub fn format_date(d: &DateTime<Utc>) -> String {
|
pub fn format_date(d: &DateTime<Utc>) -> String {
|
||||||
let utc: DateTime<Utc> = Utc::now();
|
let utc: DateTime<Utc> = Utc::now();
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ use derive_new::new;
|
|||||||
use nu_source::{b, DebugDocBuilder, Spanned};
|
use nu_source::{b, DebugDocBuilder, Spanned};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// The two types of ways to include a range end. Inclusive means to include the value (eg 1..3 inclusive would include the 3 value).
|
||||||
|
/// Exclusive excludes the value (eg 1..3 exclusive does not include 3 value)
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||||
pub enum RangeInclusion {
|
pub enum RangeInclusion {
|
||||||
Inclusive,
|
Inclusive,
|
||||||
@ -10,6 +12,7 @@ pub enum RangeInclusion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RangeInclusion {
|
impl RangeInclusion {
|
||||||
|
/// Get a RangeInclusion left bracket ready for pretty printing
|
||||||
pub fn debug_left_bracket(self) -> DebugDocBuilder {
|
pub fn debug_left_bracket(self) -> DebugDocBuilder {
|
||||||
b::delimiter(match self {
|
b::delimiter(match self {
|
||||||
RangeInclusion::Exclusive => "(",
|
RangeInclusion::Exclusive => "(",
|
||||||
@ -17,6 +20,7 @@ impl RangeInclusion {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a RangeInclusion right bracket ready for pretty printing
|
||||||
pub fn debug_right_bracket(self) -> DebugDocBuilder {
|
pub fn debug_right_bracket(self) -> DebugDocBuilder {
|
||||||
b::delimiter(match self {
|
b::delimiter(match self {
|
||||||
RangeInclusion::Exclusive => ")",
|
RangeInclusion::Exclusive => ")",
|
||||||
@ -25,6 +29,7 @@ impl RangeInclusion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The range definition, holding the starting and end point of the range
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize, new)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize, new)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub from: (Spanned<Primitive>, RangeInclusion),
|
pub from: (Spanned<Primitive>, RangeInclusion),
|
||||||
|
@ -2,6 +2,7 @@ use bigdecimal::BigDecimal;
|
|||||||
use num_traits::cast::FromPrimitive;
|
use num_traits::cast::FromPrimitive;
|
||||||
use num_traits::cast::ToPrimitive;
|
use num_traits::cast::ToPrimitive;
|
||||||
|
|
||||||
|
/// Enable big decimal serialization by providing a `serialize` function
|
||||||
pub fn serialize<S>(big_decimal: &BigDecimal, serializer: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S>(big_decimal: &BigDecimal, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
@ -14,6 +15,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enable big decimal deserialization by providing a `deserialize` function
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigDecimal, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigDecimal, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
@ -2,6 +2,7 @@ use num_bigint::BigInt;
|
|||||||
use num_traits::cast::FromPrimitive;
|
use num_traits::cast::FromPrimitive;
|
||||||
use num_traits::cast::ToPrimitive;
|
use num_traits::cast::ToPrimitive;
|
||||||
|
|
||||||
|
/// Enable big int serialization by providing a `serialize` function
|
||||||
pub fn serialize<S>(big_int: &BigInt, serializer: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S>(big_int: &BigInt, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
@ -14,6 +15,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enable big int deserialization by providing a `deserialize` function
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigInt, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<BigInt, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
Loading…
Reference in New Issue
Block a user