small, backwards compatible enhancements to std (#14763)

# Description
Small, backwards compatible enhancements to the standard library.

# User-Facing Changes

- changed `iter find`, `iter find-index`: Only consume the input stream
up to the first match.
- added `log set-level`: a small convenience command for setting the log
level
- added `$null_device`: `null-device` as a const variable, would allow
conditional sourcing if #13872 is fixed

# Tests + Formatting

- 🟢 toolkit fmt
- 🟢 toolkit clippy
- 🟢 toolkit test
- 🟢 toolkit test stdlib

# After Submitting
N/A
This commit is contained in:
Bahex 2025-01-06 20:30:07 +03:00 committed by GitHub
parent b60f91f722
commit ebabca575c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 44 additions and 51 deletions

View file

@ -41,21 +41,21 @@ export def main [
--verbose (-v) # be more verbose (namely prints the progress)
--pretty # shows the results in human-readable format: "<mean> +/- <stddev>"
] {
let times = (
let times: list<duration> = (
seq 1 $rounds | each {|i|
if $verbose { print -n $"($i) / ($rounds)\r" }
timeit { do $code } | into int | into float
timeit { do $code }
}
)
if $verbose { print $"($rounds) / ($rounds)" }
let report = {
mean: ($times | math avg | from ns)
min: ($times | math min | from ns)
max: ($times | math max | from ns)
std: ($times | math stddev | from ns)
times: ($times | each { from ns })
mean: ($times | math avg)
min: ($times | math min)
max: ($times | math max)
std: ($times | into int | math stddev | into int | into duration)
times: ($times)
}
if $pretty {
@ -64,8 +64,3 @@ export def main [
$report
}
}
# convert an integer amount of nanoseconds to a real duration
def "from ns" [] {
[$in "ns"] | str join | into duration
}

View file

@ -21,8 +21,8 @@
#
# let haystack = ["shell", "abc", "around", "nushell", "std"]
#
# let found = ($haystack | iter find {|it| $it starts-with "a" })
# let not_found = ($haystack | iter find {|it| $it mod 2 == 0})
# let found = ($haystack | iter find {|e| $e starts-with "a" })
# let not_found = ($haystack | iter find {|e| $e mod 2 == 0})
#
# assert equal $found "abc"
# assert equal $not_found null
@ -30,11 +30,7 @@
export def find [ # -> any | null
fn: closure # the closure used to perform the search
] {
try {
filter $fn | get 0?
} catch {
null
}
filter {|e| try {do $fn $e} } | try { first }
}
# Returns the index of the first element that matches the predicate or
@ -60,20 +56,9 @@ export def find [ # -> any | null
export def find-index [ # -> int
fn: closure # the closure used to perform the search
] {
let matches = (
enumerate
| each {|it|
if (do $fn $it.item) {
$it.index
}
}
)
if ($matches | is-empty) {
-1
} else {
$matches | first
}
| find {|e| $e.item | do $fn $e.item }
| try { get index } catch { -1 }
}
# Returns a new list with the separator between adjacent
@ -89,8 +74,8 @@ export def find-index [ # -> int
export def intersperse [ # -> list<any>
separator: any # the separator to be used
] {
reduce --fold [] {|it, acc|
$acc ++ [$it, $separator]
reduce --fold [] {|e, acc|
$acc ++ [$e, $separator]
}
| match $in {
[] => [],
@ -123,9 +108,9 @@ export def scan [ # -> list<any>
fn: closure # the closure to perform the scan
--noinit(-n) # remove the initial value from the result
] {
reduce --fold [$init] {|it, acc|
reduce --fold [$init] {|e, acc|
let acc_last = $acc | last
$acc ++ [($acc_last | do $fn $it $acc_last)]
$acc ++ [($acc_last | do $fn $e $acc_last)]
}
| if $noinit {
$in | skip
@ -142,22 +127,22 @@ export def scan [ # -> list<any>
# ```nu
# use std ["assert equal" "iter filter-map"]
#
# let res = ([2 5 "4" 7] | iter filter-map {|it| $it ** 2})
# let res = ([2 5 "4" 7] | iter filter-map {|e| $e ** 2})
#
# assert equal $res [4 25 49]
# ```
export def filter-map [ # -> list<any>
fn: closure # the closure to apply to the input
] {
each {|$it|
each {|$e|
try {
do $fn $it
do $fn $e
} catch {
null
}
}
| filter {|it|
$it != null
| filter {|e|
$e != null
}
}
@ -168,14 +153,14 @@ export def filter-map [ # -> list<any>
# use std ["assert equal" "iter flat-map"]
#
# let res = (
# [[1 2 3] [2 3 4] [5 6 7]] | iter flat-map {|it| $it | math sum}
# [[1 2 3] [2 3 4] [5 6 7]] | iter flat-map {|e| $e | math sum}
# )
# assert equal $res [6 9 18]
# ```
export def flat-map [ # -> list<any>
fn: closure # the closure to map to the nested structures
] {
each {|it| do $fn $it } | flatten
each {|e| do $fn $e } | flatten
}
# Zips two structures and applies a closure to each of the zips
@ -195,8 +180,8 @@ export def zip-with [ # -> list<any>
fn: closure # the closure to apply to the zips
] {
zip $other
| each {|it|
reduce {|it, acc| do $fn $acc $it }
| each {|e|
reduce {|e, acc| do $fn $acc $e }
}
}

View file

@ -313,3 +313,13 @@ export def custom [
|it, acc| $acc | str replace --all $it.0 $it.1
})
}
def "nu-complete log-level" [] {
log-level | transpose description value
}
# Change logging level
export def --env set-level [level: int@"nu-complete log-level"] {
# Keep it as a string so it can be passed to child processes
$env.NU_LOG_LEVEL = $level | into string
}

View file

@ -110,15 +110,18 @@ export def repeat [
1..$n | each { $item }
}
# null device file
export const null_device = if $nu.os-info.name == "windows" {
'\\.\NUL'
} else {
'/dev/null'
}
# return a null device file.
#
# # Examples
# run a command and ignore it's stderr output
# > cat xxx.txt e> (null-device)
export def null-device []: nothing -> path {
if ($nu.os-info.name | str downcase) == "windows" {
'\\.\NUL'
} else {
"/dev/null"
}
$null_device
}