From 77821ec8168f73cb68684b9ec06b9613889dfb65 Mon Sep 17 00:00:00 2001
From: Eugene Burkov <e.burkov@adguard.com>
Date: Fri, 27 Aug 2021 15:33:40 +0300
Subject: [PATCH] Pull request: Fix duration

Merge in DNS/adguard-home from fix-duration to master

Squashed commit of the following:

commit b6d960076e6263718ec612bc7a998c48fb92079f
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Aug 27 15:24:37 2021 +0300

    home: imp docs & fmt

commit b3d1e5dbbb9c9abe92b10a51cc1f8d7afee73e12
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Aug 27 15:16:20 2021 +0300

    home: fix duration
---
 internal/home/duration.go      | 26 +++++++++++++++++---------
 internal/home/duration_test.go |  3 +++
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/internal/home/duration.go b/internal/home/duration.go
index 2715384c..53bc1aae 100644
--- a/internal/home/duration.go
+++ b/internal/home/duration.go
@@ -23,22 +23,30 @@ type Duration struct {
 //
 func (d Duration) String() (str string) {
 	str = d.Duration.String()
-	secs := d.Seconds()
-	var secsInt int
-	if secsInt = int(secs); float64(secsInt) != secs || secsInt%60 != 0 {
-		return str
-	}
 
 	const (
 		tailMin    = len(`0s`)
 		tailMinSec = len(`0m0s`)
+
+		secsInHour = time.Hour / time.Second
+		minsInHour = time.Hour / time.Minute
 	)
 
-	if (secsInt%3600)/60 != 0 {
-		return str[:len(str)-tailMin]
-	}
+	switch rounded := d.Duration / time.Second; {
+	case
+		rounded == 0,
+		rounded*time.Second != d.Duration,
+		rounded%60 != 0:
+		// Return the uncutted value if it's either equal to zero or has
+		// fractions of a second or even whole seconds in it.
+		return str
 
-	return str[:len(str)-tailMinSec]
+	case (rounded%secsInHour)/minsInHour != 0:
+		return str[:len(str)-tailMin]
+
+	default:
+		return str[:len(str)-tailMinSec]
+	}
 }
 
 // MarshalText implements the encoding.TextMarshaler interface for Duration.
diff --git a/internal/home/duration_test.go b/internal/home/duration_test.go
index 55d98ff8..1ae121d0 100644
--- a/internal/home/duration_test.go
+++ b/internal/home/duration_test.go
@@ -46,6 +46,9 @@ func TestDuration_String(t *testing.T) {
 	}, {
 		name: "1m1.001s",
 		val:  time.Minute + time.Second + time.Millisecond,
+	}, {
+		name: "0s",
+		val:  0,
 	}}
 
 	for _, tc := range testCases {