mirror of
https://github.com/nushell/nushell.git
synced 2025-02-02 19:50:05 +01:00
Merge pull request #543 from nushell/decimals
Basic support for decimal numbers
This commit is contained in:
commit
6e932c471d
50
Cargo.lock
generated
50
Cargo.lock
generated
@ -1614,8 +1614,8 @@ dependencies = [
|
|||||||
"neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1626,6 +1626,7 @@ dependencies = [
|
|||||||
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"roxmltree 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"roxmltree 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rust_decimal 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 5.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 5.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1648,6 +1649,37 @@ dependencies = [
|
|||||||
"which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-bigint"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-complex"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@ -1683,6 +1715,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -1789,7 +1822,6 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2303,6 +2335,16 @@ name = "rust-ini"
|
|||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust_decimal"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
@ -3319,6 +3361,9 @@ dependencies = [
|
|||||||
"checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b"
|
"checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b"
|
||||||
"checksum nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4312467f8b28d909344b934207e502212fa5a3adf1bff7428b0b86a666223d"
|
"checksum nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4312467f8b28d909344b934207e502212fa5a3adf1bff7428b0b86a666223d"
|
||||||
"checksum ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602"
|
"checksum ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602"
|
||||||
|
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
|
||||||
|
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
|
||||||
|
"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
|
||||||
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
|
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
|
||||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
||||||
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
|
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
|
||||||
@ -3393,6 +3438,7 @@ dependencies = [
|
|||||||
"checksum rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a194373ef527035645a1bc21b10dc2125f73497e6e155771233eb187aedd051"
|
"checksum rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a194373ef527035645a1bc21b10dc2125f73497e6e155771233eb187aedd051"
|
||||||
"checksum rust-argon2 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81ed8d04228b44a740c8d46ff872a28e50fff3d659f307ab4da2cc502e019ff3"
|
"checksum rust-argon2 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81ed8d04228b44a740c8d46ff872a28e50fff3d659f307ab4da2cc502e019ff3"
|
||||||
"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||||
|
"checksum rust_decimal 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f7a28ded8f10361cefb69a8d8e1d195acf59344150534c165c401d6611cf013d"
|
||||||
"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
|
"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
|
||||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
"checksum rustyline 5.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8ee0838a6594169a1c5f4bb9af0fe692cc99691941710a8cc6576395ede804e"
|
"checksum rustyline 5.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8ee0838a6594169a1c5f4bb9af0fe692cc99691941710a8cc6576395ede804e"
|
||||||
|
@ -25,14 +25,15 @@ dunce = "1.0.0"
|
|||||||
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
||||||
chrono-humanize = "0.0.11"
|
chrono-humanize = "0.0.11"
|
||||||
byte-unit = "3.0.1"
|
byte-unit = "3.0.1"
|
||||||
ordered-float = {version = "1.0.2", features = ["serde"]}
|
|
||||||
futures-preview = { version = "=0.3.0-alpha.18", features = ["compat", "io-compat"] }
|
futures-preview = { version = "=0.3.0-alpha.18", features = ["compat", "io-compat"] }
|
||||||
futures-async-stream = "=0.1.0-alpha.5"
|
futures-async-stream = "=0.1.0-alpha.5"
|
||||||
futures_codec = "0.2.5"
|
futures_codec = "0.2.5"
|
||||||
|
num-traits = "0.2.8"
|
||||||
term = "0.5.2"
|
term = "0.5.2"
|
||||||
bytes = "0.4.12"
|
bytes = "0.4.12"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
pretty_env_logger = "0.3.1"
|
pretty_env_logger = "0.3.1"
|
||||||
|
rust_decimal = "1.0.3"
|
||||||
serde = { version = "1.0.98", features = ["derive"] }
|
serde = { version = "1.0.98", features = ["derive"] }
|
||||||
bson = "=0.13.0"
|
bson = "=0.13.0"
|
||||||
serde_json = "1.0.40"
|
serde_json = "1.0.40"
|
||||||
|
@ -1 +1 @@
|
|||||||
nightly-2019-08-22
|
nightly-2019-08-30
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::object::base::OF64;
|
|
||||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use bson::{decode_document, spec::BinarySubtype, Bson};
|
use bson::{decode_document, spec::BinarySubtype, Bson};
|
||||||
@ -28,7 +27,7 @@ fn convert_bson_value_to_nu_value(v: &Bson, tag: impl Into<Tag>) -> Tagged<Value
|
|||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
|
|
||||||
match v {
|
match v {
|
||||||
Bson::FloatingPoint(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag),
|
Bson::FloatingPoint(n) => Value::Primitive(Primitive::from(*n)).tagged(tag),
|
||||||
Bson::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag),
|
Bson::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag),
|
||||||
Bson::Array(a) => Value::List(
|
Bson::Array(a) => Value::List(
|
||||||
a.iter()
|
a.iter()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::object::base::OF64;
|
|
||||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -34,9 +33,7 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value, tag: impl Into<Tag>) -
|
|||||||
match v {
|
match v {
|
||||||
serde_hjson::Value::Null => Value::Primitive(Primitive::Nothing).tagged(tag),
|
serde_hjson::Value::Null => Value::Primitive(Primitive::Nothing).tagged(tag),
|
||||||
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
||||||
serde_hjson::Value::F64(n) => {
|
serde_hjson::Value::F64(n) => Value::Primitive(Primitive::from(*n)).tagged(tag),
|
||||||
Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag)
|
|
||||||
}
|
|
||||||
serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
||||||
serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
||||||
serde_hjson::Value::String(s) => {
|
serde_hjson::Value::String(s) => {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
use crate::object::base::OF64;
|
|
||||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use rusqlite::{types::ValueRef, Connection, Row, NO_PARAMS};
|
use rusqlite::{types::ValueRef, Connection, Row, NO_PARAMS};
|
||||||
@ -94,7 +93,7 @@ fn convert_sqlite_value_to_nu_value(value: ValueRef, tag: impl Into<Tag> + Clone
|
|||||||
match value {
|
match value {
|
||||||
ValueRef::Null => Value::Primitive(Primitive::String(String::from(""))).tagged(tag),
|
ValueRef::Null => Value::Primitive(Primitive::String(String::from(""))).tagged(tag),
|
||||||
ValueRef::Integer(i) => Value::Primitive(Primitive::Int(i)).tagged(tag),
|
ValueRef::Integer(i) => Value::Primitive(Primitive::Int(i)).tagged(tag),
|
||||||
ValueRef::Real(f) => Value::Primitive(Primitive::Float(OF64::from(f))).tagged(tag),
|
ValueRef::Real(f) => Value::number(f).tagged(tag),
|
||||||
t @ ValueRef::Text(_) => {
|
t @ ValueRef::Text(_) => {
|
||||||
// this unwrap is safe because we know the ValueRef is Text.
|
// this unwrap is safe because we know the ValueRef is Text.
|
||||||
Value::Primitive(Primitive::String(t.as_str().unwrap().to_string())).tagged(tag)
|
Value::Primitive(Primitive::String(t.as_str().unwrap().to_string())).tagged(tag)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::object::base::OF64;
|
|
||||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> T
|
|||||||
match v {
|
match v {
|
||||||
toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
||||||
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(tag),
|
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(tag),
|
||||||
toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag),
|
toml::Value::Float(n) => Value::Primitive(Primitive::from(*n)).tagged(tag),
|
||||||
toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag),
|
toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag),
|
||||||
toml::Value::Array(a) => Value::List(
|
toml::Value::Array(a) => Value::List(
|
||||||
a.iter()
|
a.iter()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::object::base::OF64;
|
|
||||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) ->
|
|||||||
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(tag)
|
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(tag)
|
||||||
}
|
}
|
||||||
serde_yaml::Value::Number(n) if n.is_f64() => {
|
serde_yaml::Value::Number(n) if n.is_f64() => {
|
||||||
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(tag)
|
Value::Primitive(Primitive::from(n.as_f64().unwrap())).tagged(tag)
|
||||||
}
|
}
|
||||||
serde_yaml::Value::String(s) => Value::string(s).tagged(tag),
|
serde_yaml::Value::String(s) => Value::string(s).tagged(tag),
|
||||||
serde_yaml::Value::Sequence(a) => Value::List(
|
serde_yaml::Value::Sequence(a) => Value::List(
|
||||||
|
@ -62,7 +62,7 @@ fn ps(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, She
|
|||||||
if let Ok(status) = process.status().await {
|
if let Ok(status) = process.status().await {
|
||||||
dict.insert("status", Value::string(format!("{:?}", status)));
|
dict.insert("status", Value::string(format!("{:?}", status)));
|
||||||
}
|
}
|
||||||
dict.insert("cpu", Value::float(usage.get::<ratio::percent>() as f64));
|
dict.insert("cpu", Value::number(usage.get::<ratio::percent>()));
|
||||||
yield ReturnSuccess::value(dict.into_tagged_value());
|
yield ReturnSuccess::value(dict.into_tagged_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::commands::UnevaluatedCallInfo;
|
use crate::commands::{UnevaluatedCallInfo, WholeStreamCommand};
|
||||||
use crate::commands::WholeStreamCommand;
|
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
use crate::object::Value;
|
use crate::object::Value;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -27,11 +27,16 @@ impl WholeStreamCommand for ToBSON {
|
|||||||
pub fn value_to_bson_value(v: &Value) -> Bson {
|
pub fn value_to_bson_value(v: &Value) -> Bson {
|
||||||
match v {
|
match v {
|
||||||
Value::Primitive(Primitive::Boolean(b)) => Bson::Boolean(*b),
|
Value::Primitive(Primitive::Boolean(b)) => Bson::Boolean(*b),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => Bson::I64(*b as i64),
|
// FIXME: What about really big decimals?
|
||||||
|
Value::Primitive(Primitive::Bytes(decimal)) => Bson::FloatingPoint(
|
||||||
|
(*decimal)
|
||||||
|
.to_f64()
|
||||||
|
.expect("Unimplemented BUG: What about big decimals?"),
|
||||||
|
),
|
||||||
Value::Primitive(Primitive::Date(d)) => Bson::UtcDatetime(*d),
|
Value::Primitive(Primitive::Date(d)) => Bson::UtcDatetime(*d),
|
||||||
Value::Primitive(Primitive::EndOfStream) => Bson::Null,
|
Value::Primitive(Primitive::EndOfStream) => Bson::Null,
|
||||||
Value::Primitive(Primitive::BeginningOfStream) => Bson::Null,
|
Value::Primitive(Primitive::BeginningOfStream) => Bson::Null,
|
||||||
Value::Primitive(Primitive::Float(f)) => Bson::FloatingPoint(f.into_inner()),
|
Value::Primitive(Primitive::Decimal(d)) => Bson::FloatingPoint(d.to_f64().unwrap()),
|
||||||
Value::Primitive(Primitive::Int(i)) => Bson::I64(*i),
|
Value::Primitive(Primitive::Int(i)) => Bson::I64(*i),
|
||||||
Value::Primitive(Primitive::Nothing) => Bson::Null,
|
Value::Primitive(Primitive::Nothing) => Bson::Null,
|
||||||
Value::Primitive(Primitive::String(s)) => Bson::String(s.clone()),
|
Value::Primitive(Primitive::String(s)) => Bson::String(s.clone()),
|
||||||
|
@ -45,7 +45,7 @@ pub fn value_to_csv_value(v: &Value) -> Value {
|
|||||||
fn to_string_helper(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
|
fn to_string_helper(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
match v {
|
match v {
|
||||||
Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()),
|
Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", *b as u64)),
|
Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", b)),
|
||||||
Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?),
|
Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?),
|
||||||
Value::List(_) => return Ok(String::from("[list list]")),
|
Value::List(_) => return Ok(String::from("[list list]")),
|
||||||
Value::Object(_) => return Ok(String::from("[object]")),
|
Value::Object(_) => return Ok(String::from("[object]")),
|
||||||
|
@ -25,15 +25,18 @@ impl WholeStreamCommand for ToJSON {
|
|||||||
pub fn value_to_json_value(v: &Value) -> serde_json::Value {
|
pub fn value_to_json_value(v: &Value) -> serde_json::Value {
|
||||||
match v {
|
match v {
|
||||||
Value::Primitive(Primitive::Boolean(b)) => serde_json::Value::Bool(*b),
|
Value::Primitive(Primitive::Boolean(b)) => serde_json::Value::Bool(*b),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => {
|
Value::Primitive(Primitive::Bytes(b)) => serde_json::Value::Number(
|
||||||
serde_json::Value::Number(serde_json::Number::from(*b as u64))
|
serde_json::Number::from(b.to_u64().expect("What about really big numbers")),
|
||||||
}
|
),
|
||||||
Value::Primitive(Primitive::Date(d)) => serde_json::Value::String(d.to_string()),
|
Value::Primitive(Primitive::Date(d)) => serde_json::Value::String(d.to_string()),
|
||||||
Value::Primitive(Primitive::EndOfStream) => serde_json::Value::Null,
|
Value::Primitive(Primitive::EndOfStream) => serde_json::Value::Null,
|
||||||
Value::Primitive(Primitive::BeginningOfStream) => serde_json::Value::Null,
|
Value::Primitive(Primitive::BeginningOfStream) => serde_json::Value::Null,
|
||||||
Value::Primitive(Primitive::Float(f)) => {
|
Value::Primitive(Primitive::Decimal(f)) => serde_json::Value::Number(
|
||||||
serde_json::Value::Number(serde_json::Number::from_f64(f.into_inner()).unwrap())
|
serde_json::Number::from_f64(
|
||||||
}
|
f.to_f64().expect("TODO: What about really big decimals?"),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
Value::Primitive(Primitive::Int(i)) => {
|
Value::Primitive(Primitive::Int(i)) => {
|
||||||
serde_json::Value::Number(serde_json::Number::from(*i))
|
serde_json::Value::Number(serde_json::Number::from(*i))
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ fn nu_value_to_sqlite_string(v: Value) -> String {
|
|||||||
Value::Primitive(p) => match p {
|
Value::Primitive(p) => match p {
|
||||||
Primitive::Nothing => "NULL".into(),
|
Primitive::Nothing => "NULL".into(),
|
||||||
Primitive::Int(i) => format!("{}", i),
|
Primitive::Int(i) => format!("{}", i),
|
||||||
Primitive::Float(f) => format!("{}", f.into_inner()),
|
Primitive::Decimal(f) => format!("{}", f),
|
||||||
Primitive::Bytes(u) => format!("{}", u),
|
Primitive::Bytes(u) => format!("{}", u),
|
||||||
Primitive::String(s) => format!("'{}'", s.replace("'", "''")),
|
Primitive::String(s) => format!("'{}'", s.replace("'", "''")),
|
||||||
Primitive::Boolean(true) => "1".into(),
|
Primitive::Boolean(true) => "1".into(),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
|
use crate::errors::ranged;
|
||||||
use crate::object::{Primitive, Value};
|
use crate::object::{Primitive, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -22,10 +23,12 @@ impl WholeStreamCommand for ToTOML {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
pub fn value_to_toml_value(v: &Value) -> Result<toml::Value, ShellError> {
|
||||||
match v {
|
Ok(match v {
|
||||||
Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => toml::Value::Integer(*b as i64),
|
Value::Primitive(Primitive::Bytes(b)) => {
|
||||||
|
toml::Value::Integer(ranged(b.to_i64(), "i64", b.tagged_unknown())?)
|
||||||
|
}
|
||||||
Value::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
Value::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
||||||
Value::Primitive(Primitive::EndOfStream) => {
|
Value::Primitive(Primitive::EndOfStream) => {
|
||||||
toml::Value::String("<End of Stream>".to_string())
|
toml::Value::String("<End of Stream>".to_string())
|
||||||
@ -33,13 +36,15 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
|||||||
Value::Primitive(Primitive::BeginningOfStream) => {
|
Value::Primitive(Primitive::BeginningOfStream) => {
|
||||||
toml::Value::String("<Beginning of Stream>".to_string())
|
toml::Value::String("<Beginning of Stream>".to_string())
|
||||||
}
|
}
|
||||||
Value::Primitive(Primitive::Float(f)) => toml::Value::Float(f.into_inner()),
|
Value::Primitive(Primitive::Decimal(f)) => {
|
||||||
|
toml::Value::Float(ranged(f.to_f64(), "f64", f.tagged_unknown())?)
|
||||||
|
}
|
||||||
Value::Primitive(Primitive::Int(i)) => toml::Value::Integer(*i),
|
Value::Primitive(Primitive::Int(i)) => toml::Value::Integer(*i),
|
||||||
Value::Primitive(Primitive::Nothing) => toml::Value::String("<Nothing>".to_string()),
|
Value::Primitive(Primitive::Nothing) => toml::Value::String("<Nothing>".to_string()),
|
||||||
Value::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()),
|
Value::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()),
|
||||||
Value::Primitive(Primitive::Path(s)) => toml::Value::String(s.display().to_string()),
|
Value::Primitive(Primitive::Path(s)) => toml::Value::String(s.display().to_string()),
|
||||||
|
|
||||||
Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()),
|
Value::List(l) => toml::Value::Array(collect_values(l)?),
|
||||||
Value::Block(_) => toml::Value::String("<Block>".to_string()),
|
Value::Block(_) => toml::Value::String("<Block>".to_string()),
|
||||||
Value::Binary(b) => {
|
Value::Binary(b) => {
|
||||||
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
||||||
@ -47,11 +52,21 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
|||||||
Value::Object(o) => {
|
Value::Object(o) => {
|
||||||
let mut m = toml::map::Map::new();
|
let mut m = toml::map::Map::new();
|
||||||
for (k, v) in o.entries.iter() {
|
for (k, v) in o.entries.iter() {
|
||||||
m.insert(k.clone(), value_to_toml_value(v));
|
m.insert(k.clone(), value_to_toml_value(v)?);
|
||||||
}
|
}
|
||||||
toml::Value::Table(m)
|
toml::Value::Table(m)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_values(input: &Vec<Tagged<Value>>) -> Result<Vec<toml::Value>, ShellError> {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
|
for value in input {
|
||||||
|
out.push(value_to_toml_value(value)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||||
@ -61,7 +76,7 @@ fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
|
|||||||
|
|
||||||
Ok(out
|
Ok(out
|
||||||
.values
|
.values
|
||||||
.map(move |a| match toml::to_string(&value_to_toml_value(&a)) {
|
.map(move |a| match toml::to_string(&value_to_toml_value(&a)?) {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
return ReturnSuccess::value(
|
return ReturnSuccess::value(
|
||||||
Value::Primitive(Primitive::String(val)).simple_spanned(name_span),
|
Value::Primitive(Primitive::String(val)).simple_spanned(name_span),
|
||||||
|
@ -45,7 +45,7 @@ pub fn value_to_tsv_value(v: &Value) -> Value {
|
|||||||
fn to_string_helper(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
|
fn to_string_helper(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
match v {
|
match v {
|
||||||
Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()),
|
Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", *b as u64)),
|
Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", b)),
|
||||||
Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?),
|
Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?),
|
||||||
Value::List(_) => return Ok(String::from("[list list]")),
|
Value::List(_) => return Ok(String::from("[list list]")),
|
||||||
Value::Object(_) => return Ok(String::from("[object]")),
|
Value::Object(_) => return Ok(String::from("[object]")),
|
||||||
|
@ -26,13 +26,13 @@ pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
|
|||||||
match v {
|
match v {
|
||||||
Value::Primitive(Primitive::Boolean(b)) => serde_yaml::Value::Bool(*b),
|
Value::Primitive(Primitive::Boolean(b)) => serde_yaml::Value::Bool(*b),
|
||||||
Value::Primitive(Primitive::Bytes(b)) => {
|
Value::Primitive(Primitive::Bytes(b)) => {
|
||||||
serde_yaml::Value::Number(serde_yaml::Number::from(*b as u64))
|
serde_yaml::Value::Number(serde_yaml::Number::from(b.to_f64().unwrap()))
|
||||||
}
|
}
|
||||||
Value::Primitive(Primitive::Date(d)) => serde_yaml::Value::String(d.to_string()),
|
Value::Primitive(Primitive::Date(d)) => serde_yaml::Value::String(d.to_string()),
|
||||||
Value::Primitive(Primitive::EndOfStream) => serde_yaml::Value::Null,
|
Value::Primitive(Primitive::EndOfStream) => serde_yaml::Value::Null,
|
||||||
Value::Primitive(Primitive::BeginningOfStream) => serde_yaml::Value::Null,
|
Value::Primitive(Primitive::BeginningOfStream) => serde_yaml::Value::Null,
|
||||||
Value::Primitive(Primitive::Float(f)) => {
|
Value::Primitive(Primitive::Decimal(f)) => {
|
||||||
serde_yaml::Value::Number(serde_yaml::Number::from(f.into_inner()))
|
serde_yaml::Value::Number(serde_yaml::Number::from(f.to_f64().unwrap()))
|
||||||
}
|
}
|
||||||
Value::Primitive(Primitive::Int(i)) => {
|
Value::Primitive(Primitive::Int(i)) => {
|
||||||
serde_yaml::Value::Number(serde_yaml::Number::from(*i))
|
serde_yaml::Value::Number(serde_yaml::Number::from(*i))
|
||||||
|
@ -27,7 +27,7 @@ impl PerItemCommand for Where {
|
|||||||
let stream = match condition {
|
let stream = match condition {
|
||||||
Tagged {
|
Tagged {
|
||||||
item: Value::Block(block),
|
item: Value::Block(block),
|
||||||
tag,
|
..
|
||||||
} => {
|
} => {
|
||||||
let result = block.invoke(&input_clone);
|
let result = block.invoke(&input_clone);
|
||||||
match result {
|
match result {
|
||||||
@ -39,11 +39,7 @@ impl PerItemCommand for Where {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(e)
|
||||||
format!("Could not evaluate ({})", e.to_string()),
|
|
||||||
"could not evaluate",
|
|
||||||
tag.span,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,17 @@ impl ShellError {
|
|||||||
.start()
|
.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn range_error(
|
||||||
|
expected: impl Into<String>,
|
||||||
|
actual: Tagged<impl fmt::Debug>,
|
||||||
|
) -> ShellError {
|
||||||
|
ProximateShellError::RangeError {
|
||||||
|
kind: expected.into(),
|
||||||
|
actual_kind: actual.map(|a| format!("{:?}", a)),
|
||||||
|
}
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn syntax_error(problem: Tagged<impl Into<String>>) -> ShellError {
|
pub(crate) fn syntax_error(problem: Tagged<impl Into<String>>) -> ShellError {
|
||||||
ProximateShellError::SyntaxError {
|
ProximateShellError::SyntaxError {
|
||||||
problem: problem.map(|p| p.into()),
|
problem: problem.map(|p| p.into()),
|
||||||
@ -242,6 +253,20 @@ impl ShellError {
|
|||||||
} => Diagnostic::new(Severity::Error, "Type Error")
|
} => Diagnostic::new(Severity::Error, "Type Error")
|
||||||
.with_label(Label::new_primary(span).with_message(expected)),
|
.with_label(Label::new_primary(span).with_message(expected)),
|
||||||
|
|
||||||
|
ProximateShellError::RangeError {
|
||||||
|
kind,
|
||||||
|
actual_kind:
|
||||||
|
Tagged {
|
||||||
|
item,
|
||||||
|
tag: Tag { span, .. },
|
||||||
|
},
|
||||||
|
} => Diagnostic::new(Severity::Error, "Range Error").with_label(
|
||||||
|
Label::new_primary(span).with_message(format!(
|
||||||
|
"Expected to covert {} to {}, but it was out of range",
|
||||||
|
item, kind
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
|
||||||
ProximateShellError::SyntaxError {
|
ProximateShellError::SyntaxError {
|
||||||
problem:
|
problem:
|
||||||
Tagged {
|
Tagged {
|
||||||
@ -344,6 +369,10 @@ pub enum ProximateShellError {
|
|||||||
error: ArgumentError,
|
error: ArgumentError,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
|
RangeError {
|
||||||
|
kind: String,
|
||||||
|
actual_kind: Tagged<String>,
|
||||||
|
},
|
||||||
Diagnostic(ShellDiagnostic),
|
Diagnostic(ShellDiagnostic),
|
||||||
CoerceError {
|
CoerceError {
|
||||||
left: Tagged<String>,
|
left: Tagged<String>,
|
||||||
@ -423,6 +452,7 @@ impl std::fmt::Display for ShellError {
|
|||||||
ProximateShellError::MissingValue { .. } => write!(f, "MissingValue"),
|
ProximateShellError::MissingValue { .. } => write!(f, "MissingValue"),
|
||||||
ProximateShellError::InvalidCommand { .. } => write!(f, "InvalidCommand"),
|
ProximateShellError::InvalidCommand { .. } => write!(f, "InvalidCommand"),
|
||||||
ProximateShellError::TypeError { .. } => write!(f, "TypeError"),
|
ProximateShellError::TypeError { .. } => write!(f, "TypeError"),
|
||||||
|
ProximateShellError::RangeError { .. } => write!(f, "RangeError"),
|
||||||
ProximateShellError::SyntaxError { .. } => write!(f, "SyntaxError"),
|
ProximateShellError::SyntaxError { .. } => write!(f, "SyntaxError"),
|
||||||
ProximateShellError::MissingProperty { .. } => write!(f, "MissingProperty"),
|
ProximateShellError::MissingProperty { .. } => write!(f, "MissingProperty"),
|
||||||
ProximateShellError::ArgumentError { .. } => write!(f, "ArgumentError"),
|
ProximateShellError::ArgumentError { .. } => write!(f, "ArgumentError"),
|
||||||
@ -526,3 +556,14 @@ impl<T> ShellErrorUtils<Tagged<T>> for Option<Tagged<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ranged<T>(
|
||||||
|
input: Option<T>,
|
||||||
|
expected: impl Into<String>,
|
||||||
|
actual: Tagged<impl fmt::Debug>,
|
||||||
|
) -> Result<T, ShellError> {
|
||||||
|
match input {
|
||||||
|
Some(v) => Ok(v),
|
||||||
|
None => Err(ShellError::range_error(expected, actual)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -106,7 +106,7 @@ pub(crate) fn evaluate_baseline_expr(
|
|||||||
|
|
||||||
fn evaluate_literal(literal: Tagged<hir::Literal>, source: &Text) -> Tagged<Value> {
|
fn evaluate_literal(literal: Tagged<hir::Literal>, source: &Text) -> Tagged<Value> {
|
||||||
let result = match literal.item {
|
let result = match literal.item {
|
||||||
hir::Literal::Integer(int) => Value::int(int),
|
hir::Literal::Number(int) => int.into(),
|
||||||
hir::Literal::Size(int, unit) => unit.compute(int),
|
hir::Literal::Size(int, unit) => unit.compute(int),
|
||||||
hir::Literal::String(span) => Value::string(span.slice(source)),
|
hir::Literal::String(span) => Value::string(span.slice(source)),
|
||||||
hir::Literal::Bare => Value::string(literal.span().slice(source)),
|
hir::Literal::Bare => Value::string(literal.span().slice(source)),
|
||||||
|
@ -25,12 +25,12 @@ mod utils;
|
|||||||
pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue};
|
pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue};
|
||||||
pub use crate::context::{SourceMap, SpanSource};
|
pub use crate::context::{SourceMap, SpanSource};
|
||||||
pub use crate::env::host::BasicHost;
|
pub use crate::env::host::BasicHost;
|
||||||
pub use crate::object::base::OF64;
|
|
||||||
pub use crate::parser::hir::SyntaxType;
|
pub use crate::parser::hir::SyntaxType;
|
||||||
pub use crate::plugin::{serve_plugin, Plugin};
|
pub use crate::plugin::{serve_plugin, Plugin};
|
||||||
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
|
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
|
||||||
pub use cli::cli;
|
pub use cli::cli;
|
||||||
pub use errors::ShellError;
|
pub use errors::ShellError;
|
||||||
|
pub use num_traits::cast::ToPrimitive;
|
||||||
pub use object::base::{Primitive, Value};
|
pub use object::base::{Primitive, Value};
|
||||||
pub use object::dict::{Dictionary, TaggedDictBuilder};
|
pub use object::dict::{Dictionary, TaggedDictBuilder};
|
||||||
pub use object::meta::{Span, Tag, Tagged, TaggedItem};
|
pub use object::meta::{Span, Tag, Tagged, TaggedItem};
|
||||||
|
@ -8,35 +8,16 @@ use crate::Text;
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use chrono_humanize::Humanize;
|
use chrono_humanize::Humanize;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use ordered_float::OrderedFloat;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, new, Serialize, Deserialize)]
|
|
||||||
pub struct OF64 {
|
|
||||||
pub(crate) inner: OrderedFloat<f64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OF64 {
|
|
||||||
pub(crate) fn into_inner(&self) -> f64 {
|
|
||||||
self.inner.into_inner()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<f64> for OF64 {
|
|
||||||
fn from(float: f64) -> Self {
|
|
||||||
OF64::new(OrderedFloat(float))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
pub enum Primitive {
|
pub enum Primitive {
|
||||||
Nothing,
|
Nothing,
|
||||||
Int(i64),
|
Int(i64),
|
||||||
#[allow(unused)]
|
Decimal(Decimal),
|
||||||
Float(OF64),
|
|
||||||
Bytes(u64),
|
Bytes(u64),
|
||||||
String(String),
|
String(String),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
@ -48,6 +29,24 @@ pub enum Primitive {
|
|||||||
EndOfStream,
|
EndOfStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i64> for Primitive {
|
||||||
|
fn from(int: i64) -> Primitive {
|
||||||
|
Primitive::Int(int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Decimal> for Primitive {
|
||||||
|
fn from(decimal: Decimal) -> Primitive {
|
||||||
|
Primitive::Decimal(decimal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> for Primitive {
|
||||||
|
fn from(float: f64) -> Primitive {
|
||||||
|
Primitive::Decimal(Decimal::from_f64(float).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Primitive {
|
impl Primitive {
|
||||||
pub(crate) fn type_name(&self) -> String {
|
pub(crate) fn type_name(&self) -> String {
|
||||||
use Primitive::*;
|
use Primitive::*;
|
||||||
@ -58,7 +57,7 @@ impl Primitive {
|
|||||||
EndOfStream => "end-of-stream",
|
EndOfStream => "end-of-stream",
|
||||||
Path(_) => "path",
|
Path(_) => "path",
|
||||||
Int(_) => "int",
|
Int(_) => "int",
|
||||||
Float(_) => "float",
|
Decimal(_) => "decimal",
|
||||||
Bytes(_) => "bytes",
|
Bytes(_) => "bytes",
|
||||||
String(_) => "string",
|
String(_) => "string",
|
||||||
Boolean(_) => "boolean",
|
Boolean(_) => "boolean",
|
||||||
@ -76,7 +75,7 @@ impl Primitive {
|
|||||||
EndOfStream => write!(f, "EndOfStream"),
|
EndOfStream => write!(f, "EndOfStream"),
|
||||||
Int(int) => write!(f, "{}", int),
|
Int(int) => write!(f, "{}", int),
|
||||||
Path(path) => write!(f, "{}", path.display()),
|
Path(path) => write!(f, "{}", path.display()),
|
||||||
Float(float) => write!(f, "{:?}", float),
|
Decimal(decimal) => write!(f, "{}", decimal),
|
||||||
Bytes(bytes) => write!(f, "{}", bytes),
|
Bytes(bytes) => write!(f, "{}", bytes),
|
||||||
String(string) => write!(f, "{:?}", string),
|
String(string) => write!(f, "{:?}", string),
|
||||||
Boolean(boolean) => write!(f, "{}", boolean),
|
Boolean(boolean) => write!(f, "{}", boolean),
|
||||||
@ -84,6 +83,15 @@ impl Primitive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn number(number: impl Into<Number>) -> Primitive {
|
||||||
|
let number = number.into();
|
||||||
|
|
||||||
|
match number {
|
||||||
|
Number::Int(int) => Primitive::Int(int),
|
||||||
|
Number::Decimal(decimal) => Primitive::Decimal(decimal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format(&self, field_name: Option<&String>) -> String {
|
pub fn format(&self, field_name: Option<&String>) -> String {
|
||||||
match self {
|
match self {
|
||||||
Primitive::Nothing => String::new(),
|
Primitive::Nothing => String::new(),
|
||||||
@ -105,7 +113,7 @@ impl Primitive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Primitive::Int(i) => format!("{}", i),
|
Primitive::Int(i) => format!("{}", i),
|
||||||
Primitive::Float(OF64 { inner: f }) => format!("{:.*}", 2, f.into_inner()),
|
Primitive::Decimal(decimal) => format!("{}", decimal),
|
||||||
Primitive::String(s) => format!("{}", s),
|
Primitive::String(s) => format!("{}", s),
|
||||||
Primitive::Boolean(b) => match (b, field_name) {
|
Primitive::Boolean(b) => match (b, field_name) {
|
||||||
(true, None) => format!("Yes"),
|
(true, None) => format!("Yes"),
|
||||||
@ -122,7 +130,7 @@ impl Primitive {
|
|||||||
pub fn style(&self) -> &'static str {
|
pub fn style(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Primitive::Bytes(0) => "c", // centre 'missing' indicator
|
Primitive::Bytes(0) => "c", // centre 'missing' indicator
|
||||||
Primitive::Int(_) | Primitive::Bytes(_) | Primitive::Float(_) => "r",
|
Primitive::Int(_) | Primitive::Bytes(_) | Primitive::Decimal(_) => "r",
|
||||||
_ => "",
|
_ => "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,6 +184,15 @@ pub enum Value {
|
|||||||
Block(Block),
|
Block(Block),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<Value> for Number {
|
||||||
|
fn into(self) -> Value {
|
||||||
|
match self {
|
||||||
|
Number::Int(int) => Value::int(int),
|
||||||
|
Number::Decimal(decimal) => Value::decimal(decimal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn debug_list(values: &Vec<Tagged<Value>>) -> ValuesDebug<'_> {
|
pub fn debug_list(values: &Vec<Tagged<Value>>) -> ValuesDebug<'_> {
|
||||||
ValuesDebug { values }
|
ValuesDebug { values }
|
||||||
}
|
}
|
||||||
@ -518,7 +535,11 @@ impl Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn compare(&self, operator: &Operator, other: &Value) -> Result<bool, (String, String)> {
|
pub(crate) fn compare(
|
||||||
|
&self,
|
||||||
|
operator: &Operator,
|
||||||
|
other: &Value,
|
||||||
|
) -> Result<bool, (String, String)> {
|
||||||
match operator {
|
match operator {
|
||||||
_ => {
|
_ => {
|
||||||
let coerced = coerce_compare(self, other)?;
|
let coerced = coerce_compare(self, other)?;
|
||||||
@ -566,7 +587,7 @@ impl Value {
|
|||||||
match self {
|
match self {
|
||||||
Value::Primitive(Primitive::String(s)) => Ok(s.clone()),
|
Value::Primitive(Primitive::String(s)) => Ok(s.clone()),
|
||||||
Value::Primitive(Primitive::Boolean(x)) => Ok(format!("{}", x)),
|
Value::Primitive(Primitive::Boolean(x)) => Ok(format!("{}", x)),
|
||||||
Value::Primitive(Primitive::Float(x)) => Ok(format!("{}", x.into_inner())),
|
Value::Primitive(Primitive::Decimal(x)) => Ok(format!("{}", x)),
|
||||||
Value::Primitive(Primitive::Int(x)) => Ok(format!("{}", x)),
|
Value::Primitive(Primitive::Int(x)) => Ok(format!("{}", x)),
|
||||||
Value::Primitive(Primitive::Bytes(x)) => Ok(format!("{}", x)),
|
Value::Primitive(Primitive::Bytes(x)) => Ok(format!("{}", x)),
|
||||||
// TODO: this should definitely be more general with better errors
|
// TODO: this should definitely be more general with better errors
|
||||||
@ -612,8 +633,17 @@ impl Value {
|
|||||||
Value::Primitive(Primitive::Int(s.into()))
|
Value::Primitive(Primitive::Int(s.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float(s: impl Into<OF64>) -> Value {
|
pub fn decimal(s: impl Into<Decimal>) -> Value {
|
||||||
Value::Primitive(Primitive::Float(s.into()))
|
Value::Primitive(Primitive::Decimal(s.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn number(s: impl Into<Number>) -> Value {
|
||||||
|
let num = s.into();
|
||||||
|
|
||||||
|
match num {
|
||||||
|
Number::Int(int) => Value::int(int),
|
||||||
|
Number::Decimal(decimal) => Value::decimal(decimal),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn boolean(s: impl Into<bool>) -> Value {
|
pub fn boolean(s: impl Into<bool>) -> Value {
|
||||||
@ -722,32 +752,34 @@ pub(crate) fn find(obj: &Value, field: &str, op: &Operator, rhs: &Value) -> bool
|
|||||||
(Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => i != *i2,
|
(Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => i != *i2,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
Value::Primitive(Primitive::Float(i)) => match (op, rhs) {
|
Value::Primitive(Primitive::Decimal(i)) => match (op, rhs) {
|
||||||
(Operator::LessThan, Value::Primitive(Primitive::Float(i2))) => i < *i2,
|
(Operator::LessThan, Value::Primitive(Primitive::Decimal(i2))) => i < *i2,
|
||||||
(Operator::GreaterThan, Value::Primitive(Primitive::Float(i2))) => i > *i2,
|
(Operator::GreaterThan, Value::Primitive(Primitive::Decimal(i2))) => i > *i2,
|
||||||
(Operator::LessThanOrEqual, Value::Primitive(Primitive::Float(i2))) => i <= *i2,
|
(Operator::LessThanOrEqual, Value::Primitive(Primitive::Decimal(i2))) => {
|
||||||
(Operator::GreaterThanOrEqual, Value::Primitive(Primitive::Float(i2))) => {
|
i <= *i2
|
||||||
|
}
|
||||||
|
(Operator::GreaterThanOrEqual, Value::Primitive(Primitive::Decimal(i2))) => {
|
||||||
i >= *i2
|
i >= *i2
|
||||||
}
|
}
|
||||||
(Operator::Equal, Value::Primitive(Primitive::Float(i2))) => i == *i2,
|
(Operator::Equal, Value::Primitive(Primitive::Decimal(i2))) => i == *i2,
|
||||||
(Operator::NotEqual, Value::Primitive(Primitive::Float(i2))) => i != *i2,
|
(Operator::NotEqual, Value::Primitive(Primitive::Decimal(i2))) => i != *i2,
|
||||||
(Operator::LessThan, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::LessThan, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
(i.into_inner()) < *i2 as f64
|
i < Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
(Operator::GreaterThan, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::GreaterThan, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
i.into_inner() > *i2 as f64
|
i > Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
(Operator::LessThanOrEqual, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::LessThanOrEqual, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
i.into_inner() <= *i2 as f64
|
i <= Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
(Operator::GreaterThanOrEqual, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::GreaterThanOrEqual, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
i.into_inner() >= *i2 as f64
|
i >= Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
(Operator::Equal, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::Equal, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
i.into_inner() == *i2 as f64
|
i == Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
(Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => {
|
(Operator::NotEqual, Value::Primitive(Primitive::Int(i2))) => {
|
||||||
i.into_inner() != *i2 as f64
|
i != Decimal::from(*i2)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -765,8 +797,8 @@ pub(crate) fn find(obj: &Value, field: &str, op: &Operator, rhs: &Value) -> bool
|
|||||||
|
|
||||||
enum CompareValues {
|
enum CompareValues {
|
||||||
Ints(i64, i64),
|
Ints(i64, i64),
|
||||||
Floats(OF64, OF64),
|
Decimals(Decimal, Decimal),
|
||||||
Bytes(i128, i128),
|
Bytes(u64, u64),
|
||||||
String(String, String),
|
String(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,7 +806,7 @@ impl CompareValues {
|
|||||||
fn compare(&self) -> std::cmp::Ordering {
|
fn compare(&self) -> std::cmp::Ordering {
|
||||||
match self {
|
match self {
|
||||||
CompareValues::Ints(left, right) => left.cmp(right),
|
CompareValues::Ints(left, right) => left.cmp(right),
|
||||||
CompareValues::Floats(left, right) => left.cmp(right),
|
CompareValues::Decimals(left, right) => left.cmp(right),
|
||||||
CompareValues::Bytes(left, right) => left.cmp(right),
|
CompareValues::Bytes(left, right) => left.cmp(right),
|
||||||
CompareValues::String(left, right) => left.cmp(right),
|
CompareValues::String(left, right) => left.cmp(right),
|
||||||
}
|
}
|
||||||
@ -797,10 +829,17 @@ fn coerce_compare_primitive(
|
|||||||
|
|
||||||
Ok(match (left, right) {
|
Ok(match (left, right) {
|
||||||
(Int(left), Int(right)) => CompareValues::Ints(*left, *right),
|
(Int(left), Int(right)) => CompareValues::Ints(*left, *right),
|
||||||
(Float(left), Int(right)) => CompareValues::Floats(*left, (*right as f64).into()),
|
(Int(left), Decimal(right)) => CompareValues::Decimals((*left).into(), *right),
|
||||||
(Int(left), Float(right)) => CompareValues::Floats((*left as f64).into(), *right),
|
(Int(left), Bytes(right)) => CompareValues::Bytes(*left as u64, *right),
|
||||||
(Int(left), Bytes(right)) => CompareValues::Bytes(*left as i128, *right as i128),
|
(Decimal(left), Decimal(right)) => CompareValues::Decimals(*left, *right),
|
||||||
(Bytes(left), Int(right)) => CompareValues::Bytes(*left as i128, *right as i128),
|
(Decimal(left), Int(right)) => CompareValues::Decimals(*left, (*right).into()),
|
||||||
|
(Decimal(left), Bytes(right)) => {
|
||||||
|
CompareValues::Decimals(*left, rust_decimal::Decimal::from(*right))
|
||||||
|
}
|
||||||
|
(Bytes(left), Int(right)) => CompareValues::Bytes(*left, *right as u64),
|
||||||
|
(Bytes(left), Decimal(right)) => {
|
||||||
|
CompareValues::Decimals(rust_decimal::Decimal::from(*left), *right)
|
||||||
|
}
|
||||||
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
|
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
|
||||||
_ => return Err((left.type_name(), right.type_name())),
|
_ => return Err((left.type_name(), right.type_name())),
|
||||||
})
|
})
|
||||||
|
@ -36,7 +36,7 @@ pub(crate) fn write_config(config: &IndexMap<String, Tagged<Value>>) -> Result<(
|
|||||||
let filename = location.join("config.toml");
|
let filename = location.join("config.toml");
|
||||||
touch(&filename)?;
|
touch(&filename)?;
|
||||||
|
|
||||||
let contents = value_to_toml_value(&Value::Object(Dictionary::new(config.clone())));
|
let contents = value_to_toml_value(&Value::Object(Dictionary::new(config.clone())))?;
|
||||||
|
|
||||||
let contents = toml::to_string(&contents)?;
|
let contents = toml::to_string(&contents)?;
|
||||||
|
|
||||||
|
29
src/object/process.rs
Normal file
29
src/object/process.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use crate::object::{TaggedDictBuilder, Value};
|
||||||
|
use crate::prelude::*;
|
||||||
|
use itertools::join;
|
||||||
|
use sysinfo::ProcessExt;
|
||||||
|
|
||||||
|
pub(crate) fn process_dict(proc: &sysinfo::Process, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||||
|
let mut dict = TaggedDictBuilder::new(tag);
|
||||||
|
|
||||||
|
let cmd = proc.cmd();
|
||||||
|
|
||||||
|
let cmd_value = if cmd.len() == 0 {
|
||||||
|
Value::nothing()
|
||||||
|
} else {
|
||||||
|
Value::string(join(cmd, ""))
|
||||||
|
};
|
||||||
|
|
||||||
|
dict.insert("pid", Value::int(proc.pid() as i64));
|
||||||
|
dict.insert("status", Value::string(proc.status().to_string()));
|
||||||
|
dict.insert("cpu", Value::number(proc.cpu_usage()));
|
||||||
|
|
||||||
|
match cmd_value {
|
||||||
|
Value::Primitive(Primitive::Nothing) => {
|
||||||
|
dict.insert("name", Value::string(proc.name()));
|
||||||
|
}
|
||||||
|
_ => dict.insert("name", cmd_value),
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.into_tagged_value()
|
||||||
|
}
|
@ -129,11 +129,15 @@ impl RawExpression {
|
|||||||
pub type Expression = Tagged<RawExpression>;
|
pub type Expression = Tagged<RawExpression>;
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub(crate) fn int(i: impl Into<i64>, span: impl Into<Span>) -> Expression {
|
pub(crate) fn number(i: impl Into<Number>, span: impl Into<Span>) -> Expression {
|
||||||
Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Integer(i.into())), span)
|
Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Number(i.into())), span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn size(i: impl Into<i64>, unit: impl Into<Unit>, span: impl Into<Span>) -> Expression {
|
pub(crate) fn size(
|
||||||
|
i: impl Into<Number>,
|
||||||
|
unit: impl Into<Unit>,
|
||||||
|
span: impl Into<Span>,
|
||||||
|
) -> Expression {
|
||||||
Tagged::from_simple_spanned_item(
|
Tagged::from_simple_spanned_item(
|
||||||
RawExpression::Literal(Literal::Size(i.into(), unit.into())),
|
RawExpression::Literal(Literal::Size(i.into(), unit.into())),
|
||||||
span,
|
span,
|
||||||
@ -224,8 +228,8 @@ impl From<Tagged<Path>> for Expression {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
Integer(i64),
|
Number(Number),
|
||||||
Size(i64, Unit),
|
Size(Number, Unit),
|
||||||
String(Span),
|
String(Span),
|
||||||
Bare,
|
Bare,
|
||||||
}
|
}
|
||||||
@ -233,8 +237,8 @@ pub enum Literal {
|
|||||||
impl ToDebug for Tagged<&Literal> {
|
impl ToDebug for Tagged<&Literal> {
|
||||||
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
||||||
match self.item() {
|
match self.item() {
|
||||||
Literal::Integer(int) => write!(f, "{}", *int),
|
Literal::Number(number) => write!(f, "{:?}", *number),
|
||||||
Literal::Size(int, unit) => write!(f, "{}{:?}", *int, unit),
|
Literal::Size(number, unit) => write!(f, "{:?}{:?}", *number, unit),
|
||||||
Literal::String(span) => write!(f, "{}", span.slice(source)),
|
Literal::String(span) => write!(f, "{}", span.slice(source)),
|
||||||
Literal::Bare => write!(f, "{}", self.span().slice(source)),
|
Literal::Bare => write!(f, "{}", self.span().slice(source)),
|
||||||
}
|
}
|
||||||
@ -244,7 +248,7 @@ impl ToDebug for Tagged<&Literal> {
|
|||||||
impl Literal {
|
impl Literal {
|
||||||
fn type_name(&self) -> &'static str {
|
fn type_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Literal::Integer(_) => "integer",
|
Literal::Number(..) => "number",
|
||||||
Literal::Size(..) => "size",
|
Literal::Size(..) => "size",
|
||||||
Literal::String(..) => "string",
|
Literal::String(..) => "string",
|
||||||
Literal::Bare => "string",
|
Literal::Bare => "string",
|
||||||
|
@ -5,7 +5,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
pub fn baseline_parse_single_token(token: &Token, source: &Text) -> hir::Expression {
|
pub fn baseline_parse_single_token(token: &Token, source: &Text) -> hir::Expression {
|
||||||
match *token.item() {
|
match *token.item() {
|
||||||
RawToken::Integer(int) => hir::Expression::int(int, token.span()),
|
RawToken::Number(number) => hir::Expression::number(number, token.span()),
|
||||||
RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span()),
|
RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span()),
|
||||||
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
||||||
RawToken::Variable(span) if span.slice(source) == "it" => {
|
RawToken::Variable(span) if span.slice(source) == "it" => {
|
||||||
@ -24,8 +24,8 @@ pub fn baseline_parse_token_as_number(token: &Token, source: &Text) -> hir::Expr
|
|||||||
}
|
}
|
||||||
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
||||||
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
||||||
RawToken::Integer(int) => hir::Expression::int(int, token.span()),
|
RawToken::Number(number) => hir::Expression::number(number, token.span()),
|
||||||
RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span()),
|
RawToken::Size(number, unit) => hir::Expression::size(number, unit, token.span()),
|
||||||
RawToken::Bare => hir::Expression::bare(token.span()),
|
RawToken::Bare => hir::Expression::bare(token.span()),
|
||||||
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ pub fn baseline_parse_token_as_string(token: &Token, source: &Text) -> hir::Expr
|
|||||||
}
|
}
|
||||||
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
||||||
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
||||||
RawToken::Integer(_) => hir::Expression::bare(token.span()),
|
RawToken::Number(_) => hir::Expression::bare(token.span()),
|
||||||
RawToken::Size(_, _) => hir::Expression::bare(token.span()),
|
RawToken::Size(_, _) => hir::Expression::bare(token.span()),
|
||||||
RawToken::Bare => hir::Expression::bare(token.span()),
|
RawToken::Bare => hir::Expression::bare(token.span()),
|
||||||
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
RawToken::String(span) => hir::Expression::string(span, token.span()),
|
||||||
@ -56,7 +56,7 @@ pub fn baseline_parse_token_as_path(
|
|||||||
}
|
}
|
||||||
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
RawToken::External(span) => hir::Expression::external_command(span, token.span()),
|
||||||
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
|
||||||
RawToken::Integer(_) => hir::Expression::bare(token.span()),
|
RawToken::Number(_) => hir::Expression::bare(token.span()),
|
||||||
RawToken::Size(_, _) => hir::Expression::bare(token.span()),
|
RawToken::Size(_, _) => hir::Expression::bare(token.span()),
|
||||||
RawToken::Bare => hir::Expression::file_path(
|
RawToken::Bare => hir::Expression::file_path(
|
||||||
expand_path(token.span().slice(source), context),
|
expand_path(token.span().slice(source), context),
|
||||||
|
@ -294,7 +294,7 @@ pub fn baseline_parse_path(
|
|||||||
TokenNode::Token(token) => match token.item() {
|
TokenNode::Token(token) => match token.item() {
|
||||||
RawToken::Bare => token.span().slice(source),
|
RawToken::Bare => token.span().slice(source),
|
||||||
RawToken::String(span) => span.slice(source),
|
RawToken::String(span) => span.slice(source),
|
||||||
RawToken::Integer(_)
|
RawToken::Number(_)
|
||||||
| RawToken::Size(..)
|
| RawToken::Size(..)
|
||||||
| RawToken::Variable(_)
|
| RawToken::Variable(_)
|
||||||
| RawToken::External(_) => {
|
| RawToken::External(_) => {
|
||||||
|
@ -4,6 +4,7 @@ use crate::parser::parse::{
|
|||||||
call_node::*, flag::*, operator::*, pipeline::*, token_tree::*, token_tree_builder::*,
|
call_node::*, flag::*, operator::*, pipeline::*, token_tree::*, token_tree_builder::*,
|
||||||
tokens::*, unit::*,
|
tokens::*, unit::*,
|
||||||
};
|
};
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::{Span, Tagged};
|
use crate::{Span, Tagged};
|
||||||
use nom;
|
use nom;
|
||||||
use nom::branch::*;
|
use nom::branch::*;
|
||||||
@ -18,6 +19,7 @@ use nom::dbg;
|
|||||||
use nom::*;
|
use nom::*;
|
||||||
use nom::{AsBytes, FindSubstring, IResult, InputLength, InputTake, Slice};
|
use nom::{AsBytes, FindSubstring, IResult, InputLength, InputTake, Slice};
|
||||||
use nom5_locate::{position, LocatedSpan};
|
use nom5_locate::{position, LocatedSpan};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -68,16 +70,94 @@ fn trace_step<'a, T: Debug>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_integer(input: NomSpan) -> IResult<NomSpan, Tagged<i64>> {
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
|
pub enum Number {
|
||||||
|
Int(i64),
|
||||||
|
Decimal(Decimal),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Mul for Number {
|
||||||
|
type Output = Number;
|
||||||
|
|
||||||
|
fn mul(self, other: Number) -> Number {
|
||||||
|
match (self, other) {
|
||||||
|
(Number::Int(a), Number::Int(b)) => Number::Int(a * b),
|
||||||
|
(Number::Int(a), Number::Decimal(b)) => Number::Decimal(Decimal::from(a) * b),
|
||||||
|
(Number::Decimal(a), Number::Int(b)) => Number::Decimal(a * Decimal::from(b)),
|
||||||
|
(Number::Decimal(a), Number::Decimal(b)) => Number::Decimal(a * b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For literals
|
||||||
|
impl std::ops::Mul<u32> for Number {
|
||||||
|
type Output = Number;
|
||||||
|
|
||||||
|
fn mul(self, other: u32) -> Number {
|
||||||
|
match self {
|
||||||
|
Number::Int(left) => Number::Int(left * (other as i64)),
|
||||||
|
Number::Decimal(left) => Number::Decimal(left * Decimal::from(other)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Number> for f32 {
|
||||||
|
fn into(self) -> Number {
|
||||||
|
Number::Decimal(Decimal::from_f32(self).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Number> for f64 {
|
||||||
|
fn into(self) -> Number {
|
||||||
|
Number::Decimal(Decimal::from_f64(self).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Number> for i64 {
|
||||||
|
fn into(self) -> Number {
|
||||||
|
Number::Int(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Number> for Decimal {
|
||||||
|
fn into(self) -> Number {
|
||||||
|
Number::Decimal(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn raw_number(input: NomSpan) -> IResult<NomSpan, Tagged<Number>> {
|
||||||
|
let original = input;
|
||||||
let start = input.offset;
|
let start = input.offset;
|
||||||
trace_step(input, "raw_integer", move |input| {
|
trace_step(input, "raw_decimal", move |input| {
|
||||||
let (input, neg) = opt(tag("-"))(input)?;
|
let (input, neg) = opt(tag("-"))(input)?;
|
||||||
let (input, num) = digit1(input)?;
|
let (input, head) = digit1(input)?;
|
||||||
|
let dot: IResult<NomSpan, NomSpan, (NomSpan, nom::error::ErrorKind)> = tag(".")(input);
|
||||||
|
|
||||||
|
let input = match dot {
|
||||||
|
Ok((input, dot)) => input,
|
||||||
|
|
||||||
|
// it's just an integer
|
||||||
|
Err(_) => {
|
||||||
|
return Ok((
|
||||||
|
input,
|
||||||
|
Tagged::from_simple_spanned_item(
|
||||||
|
Number::Int(int(head.fragment, neg)),
|
||||||
|
(start, input.offset),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (input, tail) = digit1(input)?;
|
||||||
|
|
||||||
let end = input.offset;
|
let end = input.offset;
|
||||||
|
|
||||||
|
let decimal = Decimal::from_str(&format!("{}.{}", head.fragment, tail.fragment))
|
||||||
|
.expect("BUG: Should have already ensured that the input is a valid decimal");
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
input,
|
input,
|
||||||
Tagged::from_simple_spanned_item(int(num.fragment, neg), (start, end)),
|
Tagged::from_simple_spanned_item(Number::Decimal(decimal), (start, end)),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -245,7 +325,7 @@ pub fn size(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
|||||||
trace_step(input, "size", move |input| {
|
trace_step(input, "size", move |input| {
|
||||||
let mut is_size = false;
|
let mut is_size = false;
|
||||||
let start = input.offset;
|
let start = input.offset;
|
||||||
let (input, int) = raw_integer(input)?;
|
let (input, number) = raw_number(input)?;
|
||||||
if let Ok((input, Some(size))) = opt(raw_unit)(input) {
|
if let Ok((input, Some(size))) = opt(raw_unit)(input) {
|
||||||
let end = input.offset;
|
let end = input.offset;
|
||||||
|
|
||||||
@ -256,7 +336,7 @@ pub fn size(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
input,
|
input,
|
||||||
TokenTreeBuilder::spanned_size((*int, *size), (start, end)),
|
TokenTreeBuilder::spanned_size((number.item, *size), (start, end)),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let end = input.offset;
|
let end = input.offset;
|
||||||
@ -266,7 +346,10 @@ pub fn size(input: NomSpan) -> IResult<NomSpan, TokenNode> {
|
|||||||
return Err(nom::Err::Error((input, nom::error::ErrorKind::Char)));
|
return Err(nom::Err::Error((input, nom::error::ErrorKind::Char)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((input, TokenTreeBuilder::spanned_int((*int), (start, end))))
|
Ok((
|
||||||
|
input,
|
||||||
|
TokenTreeBuilder::spanned_number(number.item, number.tag),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -625,12 +708,12 @@ mod tests {
|
|||||||
fn test_integer() {
|
fn test_integer() {
|
||||||
assert_leaf! {
|
assert_leaf! {
|
||||||
parsers [ size ]
|
parsers [ size ]
|
||||||
"123" -> 0..3 { Integer(123) }
|
"123" -> 0..3 { Number(Number::Int(123)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_leaf! {
|
assert_leaf! {
|
||||||
parsers [ size ]
|
parsers [ size ]
|
||||||
"-123" -> 0..4 { Integer(-123) }
|
"-123" -> 0..4 { Number(Number::Int(-123)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,12 +721,12 @@ mod tests {
|
|||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_leaf! {
|
assert_leaf! {
|
||||||
parsers [ size ]
|
parsers [ size ]
|
||||||
"123MB" -> 0..5 { Size(123, Unit::MB) }
|
"123MB" -> 0..5 { Size(Number::Int(123), Unit::MB) }
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_leaf! {
|
assert_leaf! {
|
||||||
parsers [ size ]
|
parsers [ size ]
|
||||||
"10GB" -> 0..4 { Size(10, Unit::GB) }
|
"10GB" -> 0..4 { Size(Number::Int(10), Unit::GB) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
use crate::parser::parse::flag::{Flag, FlagKind};
|
use crate::parser::parse::flag::{Flag, FlagKind};
|
||||||
use crate::parser::parse::operator::Operator;
|
use crate::parser::parse::operator::Operator;
|
||||||
|
use crate::parser::parse::parser::Number;
|
||||||
use crate::parser::parse::pipeline::{Pipeline, PipelineElement};
|
use crate::parser::parse::pipeline::{Pipeline, PipelineElement};
|
||||||
use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
|
use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
|
||||||
use crate::parser::parse::tokens::{RawToken, Token};
|
use crate::parser::parse::tokens::{RawToken, Token};
|
||||||
@ -170,9 +171,23 @@ impl TokenTreeBuilder {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spanned_int(input: impl Into<i64>, span: impl Into<Span>) -> TokenNode {
|
pub fn spanned_number(input: impl Into<Number>, span: impl Into<Span>) -> TokenNode {
|
||||||
|
match input.into() {
|
||||||
|
Number::Int(int) => TokenTreeBuilder::spanned_int(int, span),
|
||||||
|
Number::Decimal(decimal) => TokenTreeBuilder::spanned_decimal(decimal, span),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spanned_int(input: i64, span: impl Into<Span>) -> TokenNode {
|
||||||
TokenNode::Token(Token::from_simple_spanned_item(
|
TokenNode::Token(Token::from_simple_spanned_item(
|
||||||
RawToken::Integer(input.into()),
|
RawToken::Number(Number::Int(input)),
|
||||||
|
span,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spanned_decimal(input: Decimal, span: impl Into<Span>) -> TokenNode {
|
||||||
|
TokenNode::Token(Token::from_simple_spanned_item(
|
||||||
|
RawToken::Number(Number::Decimal(input)),
|
||||||
span,
|
span,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -191,7 +206,7 @@ impl TokenTreeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn spanned_size(
|
pub fn spanned_size(
|
||||||
input: (impl Into<i64>, impl Into<Unit>),
|
input: (impl Into<Number>, impl Into<Unit>),
|
||||||
span: impl Into<Span>,
|
span: impl Into<Span>,
|
||||||
) -> TokenNode {
|
) -> TokenNode {
|
||||||
let (int, unit) = (input.0.into(), input.1.into());
|
let (int, unit) = (input.0.into(), input.1.into());
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use crate::parser::parse::unit::*;
|
use crate::parser::parse::unit::*;
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::{Span, Tagged, Text};
|
use crate::{Span, Tagged, Text};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub enum RawToken {
|
pub enum RawToken {
|
||||||
Integer(i64),
|
Number(Number),
|
||||||
Size(i64, Unit),
|
Size(Number, Unit),
|
||||||
String(Span),
|
String(Span),
|
||||||
Variable(Span),
|
Variable(Span),
|
||||||
External(Span),
|
External(Span),
|
||||||
@ -15,7 +16,7 @@ pub enum RawToken {
|
|||||||
impl RawToken {
|
impl RawToken {
|
||||||
pub fn type_name(&self) -> &'static str {
|
pub fn type_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
RawToken::Integer(_) => "Integer",
|
RawToken::Number(_) => "Number",
|
||||||
RawToken::Size(..) => "Size",
|
RawToken::Size(..) => "Size",
|
||||||
RawToken::String(_) => "String",
|
RawToken::String(_) => "String",
|
||||||
RawToken::Variable(_) => "Variable",
|
RawToken::Variable(_) => "Variable",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::object::base::Value;
|
use crate::object::base::Value;
|
||||||
|
use crate::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -24,8 +25,8 @@ impl Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute(&self, size: i64) -> Value {
|
pub(crate) fn compute(&self, size: Number) -> Value {
|
||||||
Value::int(match self {
|
Value::number(match self {
|
||||||
Unit::B => size,
|
Unit::B => size,
|
||||||
Unit::KB => size * 1024,
|
Unit::KB => size * 1024,
|
||||||
Unit::MB => size * 1024 * 1024,
|
Unit::MB => size * 1024 * 1024,
|
||||||
|
@ -2,12 +2,12 @@ use std::ffi::OsStr;
|
|||||||
|
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
use heim::units::{frequency, information, thermodynamic_temperature, time};
|
||||||
|
use heim::{disk, host, memory, net, sensors};
|
||||||
use nu::{
|
use nu::{
|
||||||
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
|
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
|
||||||
Tag, Tagged, TaggedDictBuilder, Value,
|
Tag, Tagged, TaggedDictBuilder, Value,
|
||||||
};
|
};
|
||||||
use heim::{disk, memory, net, sensors, host};
|
|
||||||
use heim::units::{frequency, information, time, thermodynamic_temperature};
|
|
||||||
|
|
||||||
struct Sys;
|
struct Sys;
|
||||||
impl Sys {
|
impl Sys {
|
||||||
@ -17,30 +17,33 @@ impl Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn cpu(tag: Tag) -> Option<Tagged<Value>> {
|
async fn cpu(tag: Tag) -> Option<Tagged<Value>> {
|
||||||
match futures::future::try_join(
|
match futures::future::try_join(heim::cpu::logical_count(), heim::cpu::frequency()).await {
|
||||||
heim::cpu::logical_count(),
|
|
||||||
heim::cpu::frequency(),
|
|
||||||
).await {
|
|
||||||
Ok((num_cpu, cpu_speed)) => {
|
Ok((num_cpu, cpu_speed)) => {
|
||||||
let mut cpu_idx = TaggedDictBuilder::with_capacity(tag, 4);
|
let mut cpu_idx = TaggedDictBuilder::with_capacity(tag, 4);
|
||||||
cpu_idx.insert("cores", Primitive::Int(num_cpu as i64));
|
cpu_idx.insert("cores", Primitive::Int(num_cpu as i64));
|
||||||
|
|
||||||
let current_speed =
|
let current_speed =
|
||||||
(cpu_speed.current().get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round() / 100.0;
|
(cpu_speed.current().get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0)
|
||||||
cpu_idx.insert("current ghz", Primitive::Float(current_speed.into()));
|
.round()
|
||||||
|
/ 100.0;
|
||||||
|
cpu_idx.insert("current ghz", Primitive::number(current_speed));
|
||||||
|
|
||||||
if let Some(min_speed) = cpu_speed.min() {
|
if let Some(min_speed) = cpu_speed.min() {
|
||||||
let min_speed = (min_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round() / 100.0;
|
let min_speed =
|
||||||
cpu_idx.insert("min ghz", Primitive::Float(min_speed.into()));
|
(min_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round()
|
||||||
|
/ 100.0;
|
||||||
|
cpu_idx.insert("min ghz", Primitive::number(min_speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(max_speed) = cpu_speed.max() {
|
if let Some(max_speed) = cpu_speed.max() {
|
||||||
let max_speed = (max_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round() / 100.0;
|
let max_speed =
|
||||||
cpu_idx.insert("max ghz", Primitive::Float(max_speed.into()));
|
(max_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round()
|
||||||
|
/ 100.0;
|
||||||
|
cpu_idx.insert("max ghz", Primitive::number(max_speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(cpu_idx.into_tagged_value())
|
Some(cpu_idx.into_tagged_value())
|
||||||
},
|
}
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,19 +51,29 @@ async fn cpu(tag: Tag) -> Option<Tagged<Value>> {
|
|||||||
async fn mem(tag: Tag) -> Tagged<Value> {
|
async fn mem(tag: Tag) -> Tagged<Value> {
|
||||||
let mut dict = TaggedDictBuilder::with_capacity(tag, 4);
|
let mut dict = TaggedDictBuilder::with_capacity(tag, 4);
|
||||||
|
|
||||||
let (memory_result, swap_result) = futures::future::join(
|
let (memory_result, swap_result) =
|
||||||
memory::memory(),
|
futures::future::join(memory::memory(), memory::swap()).await;
|
||||||
memory::swap()
|
|
||||||
).await;
|
|
||||||
|
|
||||||
if let Ok(memory) = memory_result {
|
if let Ok(memory) = memory_result {
|
||||||
dict.insert("total", Value::bytes(memory.total().get::<information::byte>()));
|
dict.insert(
|
||||||
dict.insert("free", Value::bytes(memory.free().get::<information::byte>()));
|
"total",
|
||||||
|
Value::bytes(memory.total().get::<information::byte>()),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"free",
|
||||||
|
Value::bytes(memory.free().get::<information::byte>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(swap) = swap_result {
|
if let Ok(swap) = swap_result {
|
||||||
dict.insert("swap total", Value::bytes(swap.total().get::<information::byte>()));
|
dict.insert(
|
||||||
dict.insert("swap free", Value::bytes(swap.free().get::<information::byte>()));
|
"swap total",
|
||||||
|
Value::bytes(swap.total().get::<information::byte>()),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"swap free",
|
||||||
|
Value::bytes(swap.free().get::<information::byte>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
dict.into_tagged_value()
|
dict.into_tagged_value()
|
||||||
@ -69,10 +82,8 @@ async fn mem(tag: Tag) -> Tagged<Value> {
|
|||||||
async fn host(tag: Tag) -> Tagged<Value> {
|
async fn host(tag: Tag) -> Tagged<Value> {
|
||||||
let mut dict = TaggedDictBuilder::with_capacity(tag, 6);
|
let mut dict = TaggedDictBuilder::with_capacity(tag, 6);
|
||||||
|
|
||||||
let (platform_result, uptime_result) = futures::future::join(
|
let (platform_result, uptime_result) =
|
||||||
host::platform(),
|
futures::future::join(host::platform(), host::uptime()).await;
|
||||||
host::uptime(),
|
|
||||||
).await;
|
|
||||||
|
|
||||||
// OS
|
// OS
|
||||||
if let Ok(platform) = platform_result {
|
if let Ok(platform) = platform_result {
|
||||||
@ -133,9 +144,18 @@ async fn disks(tag: Tag) -> Option<Value> {
|
|||||||
dict.insert("mount", Value::string(part.mount_point().to_string_lossy()));
|
dict.insert("mount", Value::string(part.mount_point().to_string_lossy()));
|
||||||
|
|
||||||
if let Ok(usage) = disk::usage(part.mount_point().to_path_buf()).await {
|
if let Ok(usage) = disk::usage(part.mount_point().to_path_buf()).await {
|
||||||
dict.insert("total", Value::bytes(usage.total().get::<information::byte>()));
|
dict.insert(
|
||||||
dict.insert("used", Value::bytes(usage.used().get::<information::byte>()));
|
"total",
|
||||||
dict.insert("free", Value::bytes(usage.free().get::<information::byte>()));
|
Value::bytes(usage.total().get::<information::byte>()),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"used",
|
||||||
|
Value::bytes(usage.used().get::<information::byte>()),
|
||||||
|
);
|
||||||
|
dict.insert(
|
||||||
|
"free",
|
||||||
|
Value::bytes(usage.free().get::<information::byte>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push(dict.into_tagged_value());
|
output.push(dict.into_tagged_value());
|
||||||
@ -169,13 +189,13 @@ async fn battery(tag: Tag) -> Option<Value> {
|
|||||||
if let Some(time_to_full) = battery.time_to_full() {
|
if let Some(time_to_full) = battery.time_to_full() {
|
||||||
dict.insert(
|
dict.insert(
|
||||||
"mins to full",
|
"mins to full",
|
||||||
Value::float(time_to_full.get::<battery::units::time::minute>() as f64),
|
Value::number(time_to_full.get::<battery::units::time::minute>()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if let Some(time_to_empty) = battery.time_to_empty() {
|
if let Some(time_to_empty) = battery.time_to_empty() {
|
||||||
dict.insert(
|
dict.insert(
|
||||||
"mins to empty",
|
"mins to empty",
|
||||||
Value::float(time_to_empty.get::<battery::units::time::minute>() as f64),
|
Value::number(time_to_empty.get::<battery::units::time::minute>()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
output.push(dict.into_tagged_value());
|
output.push(dict.into_tagged_value());
|
||||||
@ -202,12 +222,25 @@ async fn temp(tag: Tag) -> Option<Value> {
|
|||||||
if let Some(label) = sensor.label() {
|
if let Some(label) = sensor.label() {
|
||||||
dict.insert("label", Value::string(label));
|
dict.insert("label", Value::string(label));
|
||||||
}
|
}
|
||||||
dict.insert("temp", Value::float(sensor.current().get::<thermodynamic_temperature::degree_celsius>() as f64));
|
dict.insert(
|
||||||
|
"temp",
|
||||||
|
Value::number(
|
||||||
|
sensor
|
||||||
|
.current()
|
||||||
|
.get::<thermodynamic_temperature::degree_celsius>(),
|
||||||
|
),
|
||||||
|
);
|
||||||
if let Some(high) = sensor.high() {
|
if let Some(high) = sensor.high() {
|
||||||
dict.insert("high", Value::float(high.get::<thermodynamic_temperature::degree_celsius>() as f64));
|
dict.insert(
|
||||||
|
"high",
|
||||||
|
Value::number(high.get::<thermodynamic_temperature::degree_celsius>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if let Some(critical) = sensor.critical() {
|
if let Some(critical) = sensor.critical() {
|
||||||
dict.insert("critical", Value::float(critical.get::<thermodynamic_temperature::degree_celsius>() as f64));
|
dict.insert(
|
||||||
|
"critical",
|
||||||
|
Value::number(critical.get::<thermodynamic_temperature::degree_celsius>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push(dict.into_tagged_value());
|
output.push(dict.into_tagged_value());
|
||||||
@ -228,8 +261,14 @@ async fn net(tag: Tag) -> Option<Value> {
|
|||||||
if let Ok(nic) = nic {
|
if let Ok(nic) = nic {
|
||||||
let mut network_idx = TaggedDictBuilder::with_capacity(tag, 3);
|
let mut network_idx = TaggedDictBuilder::with_capacity(tag, 3);
|
||||||
network_idx.insert("name", Value::string(nic.interface()));
|
network_idx.insert("name", Value::string(nic.interface()));
|
||||||
network_idx.insert("sent", Value::bytes(nic.bytes_sent().get::<information::byte>()));
|
network_idx.insert(
|
||||||
network_idx.insert("recv", Value::bytes(nic.bytes_recv().get::<information::byte>()));
|
"sent",
|
||||||
|
Value::bytes(nic.bytes_sent().get::<information::byte>()),
|
||||||
|
);
|
||||||
|
network_idx.insert(
|
||||||
|
"recv",
|
||||||
|
Value::bytes(nic.bytes_recv().get::<information::byte>()),
|
||||||
|
);
|
||||||
output.push(network_idx.into_tagged_value());
|
output.push(network_idx.into_tagged_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,17 +282,9 @@ async fn net(tag: Tag) -> Option<Value> {
|
|||||||
async fn sysinfo(tag: Tag) -> Vec<Tagged<Value>> {
|
async fn sysinfo(tag: Tag) -> Vec<Tagged<Value>> {
|
||||||
let mut sysinfo = TaggedDictBuilder::with_capacity(tag, 7);
|
let mut sysinfo = TaggedDictBuilder::with_capacity(tag, 7);
|
||||||
|
|
||||||
let (host, cpu, disks, memory, temp) = futures::future::join5(
|
let (host, cpu, disks, memory, temp) =
|
||||||
host(tag),
|
futures::future::join5(host(tag), cpu(tag), disks(tag), mem(tag), temp(tag)).await;
|
||||||
cpu(tag),
|
let (net, battery) = futures::future::join(net(tag), battery(tag)).await;
|
||||||
disks(tag),
|
|
||||||
mem(tag),
|
|
||||||
temp(tag),
|
|
||||||
).await;
|
|
||||||
let (net, battery) = futures::future::join(
|
|
||||||
net(tag),
|
|
||||||
battery(tag),
|
|
||||||
).await;
|
|
||||||
|
|
||||||
sysinfo.insert_tagged("host", host);
|
sysinfo.insert_tagged("host", host);
|
||||||
if let Some(cpu) = cpu {
|
if let Some(cpu) = cpu {
|
||||||
|
@ -63,6 +63,7 @@ pub(crate) use crate::object::meta::{Tag, Tagged, TaggedItem};
|
|||||||
pub(crate) use crate::object::types::ExtractType;
|
pub(crate) use crate::object::types::ExtractType;
|
||||||
pub(crate) use crate::object::{Primitive, Value};
|
pub(crate) use crate::object::{Primitive, Value};
|
||||||
pub(crate) use crate::parser::hir::SyntaxType;
|
pub(crate) use crate::parser::hir::SyntaxType;
|
||||||
|
pub(crate) use crate::parser::parse::parser::Number;
|
||||||
pub(crate) use crate::parser::registry::Signature;
|
pub(crate) use crate::parser::registry::Signature;
|
||||||
pub(crate) use crate::shell::filesystem_shell::FilesystemShell;
|
pub(crate) use crate::shell::filesystem_shell::FilesystemShell;
|
||||||
pub(crate) use crate::shell::shell_manager::ShellManager;
|
pub(crate) use crate::shell::shell_manager::ShellManager;
|
||||||
@ -74,6 +75,8 @@ pub(crate) use crate::Text;
|
|||||||
pub(crate) use futures::stream::BoxStream;
|
pub(crate) use futures::stream::BoxStream;
|
||||||
pub(crate) use futures::{FutureExt, Stream, StreamExt};
|
pub(crate) use futures::{FutureExt, Stream, StreamExt};
|
||||||
pub(crate) use futures_async_stream::async_stream_block;
|
pub(crate) use futures_async_stream::async_stream_block;
|
||||||
|
pub(crate) use num_traits::cast::{FromPrimitive, ToPrimitive};
|
||||||
|
pub(crate) use rust_decimal::Decimal;
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) use serde::{Deserialize, Serialize};
|
pub(crate) use serde::{Deserialize, Serialize};
|
||||||
pub(crate) use std::collections::VecDeque;
|
pub(crate) use std::collections::VecDeque;
|
||||||
|
@ -116,7 +116,7 @@ fn paint_token_node(token_node: &TokenNode, line: &str) -> String {
|
|||||||
TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)),
|
TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)),
|
||||||
TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)),
|
TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)),
|
||||||
TokenNode::Token(Tagged {
|
TokenNode::Token(Tagged {
|
||||||
item: RawToken::Integer(..),
|
item: RawToken::Number(..),
|
||||||
..
|
..
|
||||||
}) => Color::Purple.bold().paint(token_node.span().slice(line)),
|
}) => Color::Purple.bold().paint(token_node.span().slice(line)),
|
||||||
TokenNode::Token(Tagged {
|
TokenNode::Token(Tagged {
|
||||||
|
Loading…
Reference in New Issue
Block a user