rusty-ts
A Rust port of the moreutils ts utility: prefix each line of stdin with a timestamp. Static binaries on Linux, macOS, and Windows; works with or without a Rust toolchain via cargo install or cargo binstall. Default mode adds a few niceties moreutils doesn't have (-u/--utc, --tz=<IANA>, env-var defaults, shell completions); Strict mode reverts every observable surface to byte-identical moreutils behavior for drop-in migration.
Part of the Rusty portfolio — a collection of small Rust ports of utilities missing from the Rust ecosystem.
Install
With a Rust toolchain
To also install the ts binary alias (auto-enables Strict mode on invocation):
Without a Rust toolchain (prebuilt binaries via cargo-binstall)
Direct download
Per-target archives are attached to each GitHub Release. Linux x86_64/aarch64, macOS x86_64/aarch64, Windows x86_64. Each archive contains the binary plus pre-generated shell-completion scripts for bash, zsh, fish, and PowerShell.
Usage
# Default format (matches moreutils ts: `%b %d %H:%M:%S`)
|
# Custom strftime format
|
# Elapsed time since previous line / since program start (monotonic clock)
|
|
# UTC or named IANA timezone
|
|
# Convert pre-timestamped lines to relative form (Default-mode subset: ISO-8601, RFC-3339, Unix epoch)
|
# Strict moreutils-compat mode (rejects -u/--tz, expands -r to full moreutils set, mirrors stderr layout)
|
RUSTY_TS_STRICT=1 |
|
# Implicit default format via env var (Default mode only)
RUSTY_TS_FORMAT='[%H:%M:%S]' |
# Shell completions
Compatibility statement (vs moreutils ts)
Byte-level fidelity is verified by snapshot tests against captured moreutils-ts output under a pinned environment: TZ=UTC and LC_ALL=C.UTF-8. The snapshot reference is moreutils at a pinned upstream commit recorded in fixtures/README.md.
Documented intentional divergences from moreutils ts (also enumerated in docs/COMPATIBILITY.md — generated from the CLI definition and drift-tested in CI):
-rrecognized-timestamp set is a subset in Default mode: ISO-8601, RFC-3339, and Unix epoch (integer + fractional) only.--strictexpands recognition to the full moreutils set.-u/--utcflag: not present in moreutils. Default-mode addition; rejected in Strict mode.--tz=<IANA>flag: not present in moreutils. Default-mode addition; rejected in Strict mode.RUSTY_TS_FORMATenv var: not defined by moreutils. Honored in Default mode; ignored in Strict mode.completionssubcommand: not present in moreutils. Default-mode addition; rejected in Strict mode.
In Strict mode, exit codes, stderr diagnostic text, and --help / --version layouts match moreutils. See docs/COMPATIBILITY.md for the full per-flag matrix and exit-code table.
Library API
The crate exposes a public Rust API for programmatic use. The canonical surface is byte-typed (preserves non-UTF-8 payload bytes per FR-011); a String-typed convenience adapter is available for the common UTF-8 case.
use ;
use ;
let mut ts = new
.format
.compat
.timezone
.build?;
let input = new;
for line in ts.prefix_lines
# Ok::
To use the library without pulling in the CLI dependencies:
[]
= { = "0.1", = false }
Relationship to moreutils
rusty-ts is a clean-room Rust reimplementation of the moreutils ts utility. It contains no source code from moreutils — only a from-scratch Rust implementation that observes the documented behavior of moreutils ts and reproduces it.
The moreutils ts Perl script is © 2006 Joey Hess and licensed under the GNU GPL. That license governs the Perl source code. Behavioral interfaces (flag set, output format) are not copyrightable, so a clean-room reimplementation under a different license is well-established practice — the same posture as uutils/coreutils (MIT-licensed reimplementation of GPL-licensed GNU coreutils).
rusty-ts does not distribute or derive from the moreutils source code. Snapshot tests in this repository compare rusty-ts runtime output against captured moreutils ts runtime output (captured by running moreutils against fixtures and recording bytes) — that is not source-code derivation either. The captured output bytes are facts, not creative expression.
If you want the original moreutils ts, install it via your platform's package manager (apt install moreutils, brew install moreutils, etc.) — that is unaffected by this port's existence.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.