nushell icon indicating copy to clipboard operation
nushell copied to clipboard

Accept integer and decimal inputs for `into duration`

Open NotTheDr01ds opened this issue 2 years ago • 7 comments

Related problem

When we need to use a duration, e.g., for sleep, typically the value is coming from an external source that isn't going to provide a Nushell duration type.

For example, if I get a backoff result from a REST API, it's going to be a numeric value such as "5" (or the string representation thereof).

Currently, unless I'm missing some idiom, we have to go through a (IMHO) hokey step where we first represent the duration as a string (e.g., $"($backoff)sec"), then convert that string into duration. That results in this unwieldy code (real example from API use):

sleep ( $"($res.backoff)sec" | into duration )

Describe the solution you'd like

Allow int and decimal input to into duration with a --from argument specifying the duration unit.

> 5 | into duration --from sec
5sec

Describe alternatives you've considered

Alternatively, for sleep, it would be very nice to have it act like so many other sleep commands and just accept an int/decimal value in seconds:

> sleep 1.5

I'll fill out a separate feature request for this.

Additional context and details

No response

NotTheDr01ds avatar Aug 01 '23 14:08 NotTheDr01ds

I'd probably support adding something like this to format duration but we just removed a bunch of conversion stuff from into duration and put it there.

I'd also probably support sleep taking ints or floats and treating them like seconds for a QOL improvement.

fdncred avatar Aug 01 '23 14:08 fdncred

@fdncred

I'd probably support adding something like this to format duration but we just removed a bunch of conversion stuff from into duration and put it there.

Wouldn't it be more appropriate to say that "formatting stuff", rather than "conversion stuff", was moved out of into duration?

I did see the commit for format duration, and I definitely agree that the --convert stuff didn't belong in into duration. That's because the output of into duration --convert <unit> wasn't even a valid duration - It was a "format"ted string. The output of into duration should, I agree, be a duration ;-).

But converting from one Nushell type to another is really the whole point of all of the into commands, isn't it? To wit:

> help into
Commands to convert data from one type to another.
....
Subcommands:
  into binary - Convert value to a binary primitive.
  into bool - Convert value to boolean.
  into datetime - Convert text or timestamp into a datetime.
  into decimal - Convert text into a decimal.
  into duration - Convert value to duration.
  into filesize - Convert value to filesize.
  into int - Convert value to integer.
  into record - Convert value to record.
  into sqlite - Convert table into a SQLite database.
  into string - Convert value to string.

I can't really emphasize all the instances of convert in there since it's a code-block, but ... ;-)

Further, if you put this type of behavior in format duration, then you either have to specify a duration to output to (which is highly unnecessary here). E.g.:

> 1.5 | format duration --from sec sec
1.5sec
> 1.5 | formation duration --from sec ms
1500ms

I just care that I get a duration - Specifying the output unit shouldn't be necessary.

Or you could have format duration work without an output unit, which again is a bit weird for a command named format duration. E.g.:

> 1.5 | format duration --from sec
1.5sec

Honestly, it seems better in into duration with all the other "type-to-type" conversion commands ;-)

NotTheDr01ds avatar Aug 01 '23 18:08 NotTheDr01ds

I could warm up to such a behavior with a --unit/--from flag. I think a good default value for it might be the underlying nanoseconds. I think we have a few places where this may leak out already (some math ops with mixed types :P). We either completely make this implementation detail opaque by blocking the implicit conversion or commiting to it (then changes to that would be breaking)

sholderbach avatar Aug 01 '23 19:08 sholderbach

I think a good default value for it might be the underlying nanoseconds.

Funny, I was just adding that thought.

> 1sec | into int
1000000000
> 10 | into string | into int
10
> 1sec | into int | into duration
# would be nice for starters, yes

NotTheDr01ds avatar Aug 01 '23 19:08 NotTheDr01ds

And yes, --unit is probably better (and more consistent).

NotTheDr01ds avatar Aug 01 '23 19:08 NotTheDr01ds

You make a convincing argument @NotTheDr01ds. :) I think this is a good feature to have somewhere. I'm up for whatever.

fdncred avatar Aug 01 '23 20:08 fdncred

Integers already work like this:

5 | into duration --unit sec

but, sadly, floats are not yet supported:

1.5 | into duration --unit sec

even though you can do this when converting from a string:

"1.5sec" | into duration

weirdan avatar Aug 16 '24 20:08 weirdan

Integers already work like this:

5 | into duration --unit sec but, sadly, floats are not yet supported:

If everyone agrees that we want to provide the second option with floats, I can take a look at it

LoicRiegel avatar Mar 10 '25 22:03 LoicRiegel

I'd support floats here

fdncred avatar Mar 11 '25 02:03 fdncred

Since the PR has been merged, should we close this?

LoicRiegel avatar Apr 03 '25 12:04 LoicRiegel