mirror of
https://github.com/nushell/nushell.git
synced 2025-08-18 18:38:52 +02:00
@@ -187,6 +187,7 @@ impl TaggedDictBuilder {
|
||||
builder.into_value()
|
||||
}
|
||||
|
||||
/// Create a new builder with a pre-defined capacity
|
||||
pub fn with_capacity(tag: impl Into<Tag>, n: usize) -> TaggedDictBuilder {
|
||||
TaggedDictBuilder {
|
||||
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>) {
|
||||
self.dict
|
||||
.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>) {
|
||||
self.dict.insert(key.into(), value.into());
|
||||
}
|
||||
|
||||
/// Convert the dictionary into a tagged Value using the original tag
|
||||
pub fn into_value(self) -> Value {
|
||||
let tag = self.tag.clone();
|
||||
self.into_untagged_value().into_value(tag)
|
||||
}
|
||||
|
||||
/// Convert the dictionary into an UntaggedValue
|
||||
pub fn into_untagged_value(self) -> UntaggedValue {
|
||||
UntaggedValue::Row(Dictionary { entries: self.dict })
|
||||
}
|
||||
|
||||
/// Returns true if the dictionary is empty, false otherwise
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.dict.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TaggedDictBuilder> for Value {
|
||||
/// Convert a builder into a tagged Value
|
||||
fn from(input: TaggedDictBuilder) -> Value {
|
||||
input.into_value()
|
||||
}
|
||||
|
@@ -6,6 +6,9 @@ use serde::{Deserialize, Serialize};
|
||||
use std::cmp::{Ord, Ordering, PartialOrd};
|
||||
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)]
|
||||
pub struct Scope {
|
||||
pub it: Value,
|
||||
@@ -13,6 +16,7 @@ pub struct Scope {
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
/// Create a new scope
|
||||
pub fn new(it: Value) -> Scope {
|
||||
Scope {
|
||||
it,
|
||||
@@ -22,6 +26,7 @@ impl Scope {
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
/// Create an empty scope
|
||||
pub fn empty() -> Scope {
|
||||
Scope {
|
||||
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 {
|
||||
Scope {
|
||||
it: value,
|
||||
|
@@ -11,32 +11,52 @@ use num_traits::cast::{FromPrimitive, ToPrimitive};
|
||||
use serde::{Deserialize, Serialize};
|
||||
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)]
|
||||
pub enum Primitive {
|
||||
/// An empty value
|
||||
Nothing,
|
||||
/// A "big int", an integer with arbitrarily large size (aka not limited to 64-bit)
|
||||
#[serde(with = "serde_bigint")]
|
||||
Int(BigInt),
|
||||
/// A "big decimal", an decimal number with arbitrarily large size (aka not limited to 64-bit)
|
||||
#[serde(with = "serde_bigdecimal")]
|
||||
Decimal(BigDecimal),
|
||||
/// A count in the number of bytes, used as a filesize
|
||||
Bytes(u64),
|
||||
/// A string value
|
||||
String(String),
|
||||
/// A string value with an implied carriage return (or cr/lf) ending
|
||||
Line(String),
|
||||
/// A path to travel to reach a value in a table
|
||||
ColumnPath(ColumnPath),
|
||||
/// A glob pattern, eg foo*
|
||||
Pattern(String),
|
||||
/// A boolean value
|
||||
Boolean(bool),
|
||||
/// A date value, in 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>),
|
||||
/// A file path
|
||||
Path(PathBuf),
|
||||
/// A vector of raw binary data
|
||||
#[serde(with = "serde_bytes")]
|
||||
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,
|
||||
/// End of stream marker, a pseudo-value not intended for tables
|
||||
EndOfStream,
|
||||
}
|
||||
|
||||
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> {
|
||||
match self {
|
||||
Primitive::Int(int) => match int.to_u64() {
|
||||
@@ -56,12 +76,14 @@ impl Primitive {
|
||||
}
|
||||
|
||||
impl From<BigDecimal> for Primitive {
|
||||
/// Helper to convert from decimals to a Primitive value
|
||||
fn from(decimal: BigDecimal) -> Primitive {
|
||||
Primitive::Decimal(decimal)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Primitive {
|
||||
/// Helper to convert from 64-bit float to a Primitive value
|
||||
fn from(float: f64) -> Primitive {
|
||||
if let Some(f) = BigDecimal::from_f64(float) {
|
||||
Primitive::Decimal(f)
|
||||
@@ -72,6 +94,7 @@ impl From<f64> for Primitive {
|
||||
}
|
||||
|
||||
impl ShellTypeName for Primitive {
|
||||
/// Get the name of the type of a Primitive value
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
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 {
|
||||
match primitive {
|
||||
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 {
|
||||
let (minutes, seconds) = (sec / 60, sec % 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 {
|
||||
let utc: DateTime<Utc> = Utc::now();
|
||||
|
||||
|
@@ -3,6 +3,8 @@ use derive_new::new;
|
||||
use nu_source::{b, DebugDocBuilder, Spanned};
|
||||
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)]
|
||||
pub enum RangeInclusion {
|
||||
Inclusive,
|
||||
@@ -10,6 +12,7 @@ pub enum RangeInclusion {
|
||||
}
|
||||
|
||||
impl RangeInclusion {
|
||||
/// Get a RangeInclusion left bracket ready for pretty printing
|
||||
pub fn debug_left_bracket(self) -> DebugDocBuilder {
|
||||
b::delimiter(match self {
|
||||
RangeInclusion::Exclusive => "(",
|
||||
@@ -17,6 +20,7 @@ impl RangeInclusion {
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a RangeInclusion right bracket ready for pretty printing
|
||||
pub fn debug_right_bracket(self) -> DebugDocBuilder {
|
||||
b::delimiter(match self {
|
||||
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)]
|
||||
pub struct Range {
|
||||
pub from: (Spanned<Primitive>, RangeInclusion),
|
||||
|
@@ -2,6 +2,7 @@ use bigdecimal::BigDecimal;
|
||||
use num_traits::cast::FromPrimitive;
|
||||
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>
|
||||
where
|
||||
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>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
|
@@ -2,6 +2,7 @@ use num_bigint::BigInt;
|
||||
use num_traits::cast::FromPrimitive;
|
||||
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>
|
||||
where
|
||||
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>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
|
Reference in New Issue
Block a user