From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9AA366BCCA for ; Thu, 18 Mar 2021 13:01:40 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 89A1918C34 for ; Thu, 18 Mar 2021 13:01:10 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 719C318C1C for ; Thu, 18 Mar 2021 13:01:09 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1AFDC4635E for ; Thu, 18 Mar 2021 13:01:09 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Thu, 18 Mar 2021 13:01:04 +0100 Message-Id: <20210318120108.26423-2-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210318120108.26423-1-d.csapak@proxmox.com> References: <20210318120108.26423-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.182 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [time.rs] Subject: [pbs-devel] [PATCH proxmox-backup v2 1/5] tools/systemd/time: implement some Traits for TimeSpan X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Mar 2021 12:01:40 -0000 namely * From (to convert easily from duration to timespan) * Display (for better formatting) Signed-off-by: Dominik Csapak --- changes from v1: * reorder msec, usec * improve display trait code src/tools/systemd/time.rs | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/tools/systemd/time.rs b/src/tools/systemd/time.rs index 7cc42415..cbcb23df 100644 --- a/src/tools/systemd/time.rs +++ b/src/tools/systemd/time.rs @@ -141,6 +141,88 @@ impl From for f64 { } } +impl From for TimeSpan { + fn from(duration: std::time::Duration) -> Self { + let mut duration = duration.as_nanos(); + let nsec = (duration % 1000) as u64; + duration /= 1000; + let usec = (duration % 1000) as u64; + duration /= 1000; + let msec = (duration % 1000) as u64; + duration /= 1000; + let seconds = (duration % 60) as u64; + duration /= 60; + let minutes = (duration % 60) as u64; + duration /= 60; + let hours = (duration % 24) as u64; + duration /= 24; + let years = (duration as f64 / 365.25) as u64; + let ydays = (duration as f64 % 365.25) as u64; + let months = (ydays as f64 / 30.44) as u64; + let mdays = (ydays as f64 % 30.44) as u64; + let weeks = mdays / 7; + let days = mdays % 7; + Self { + nsec, + usec, + msec, + seconds, + minutes, + hours, + days, + weeks, + months, + years, + } + } +} + +impl std::fmt::Display for TimeSpan { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + let mut first = true; + { // block scope for mutable borrows + let mut do_write = |v: u64, unit: &str| -> Result<(), std::fmt::Error> { + if !first { + write!(f, " ")?; + } + first = false; + write!(f, "{}{}", v, unit) + }; + if self.years > 0 { + do_write(self.years, "y")?; + } + if self.months > 0 { + do_write(self.months, "m")?; + } + if self.weeks > 0 { + do_write(self.weeks, "w")?; + } + if self.days > 0 { + do_write(self.days, "d")?; + } + if self.hours > 0 { + do_write(self.hours, "h")?; + } + if self.minutes > 0 { + do_write(self.minutes, "min")?; + } + } + if !first { + write!(f, " ")?; + } + let seconds = self.seconds as f64 + (self.msec as f64 / 1000.0); + if seconds >= 0.1 { + if seconds >= 1.0 || !first { + write!(f, "{:.0}s", seconds)?; + } else { + write!(f, "{:.1}s", seconds)?; + } + } else if first { + write!(f, "<0.1s")?; + } + Ok(()) + } +} pub fn verify_time_span(i: &str) -> Result<(), Error> { parse_time_span(i)?; -- 2.20.1