go-duration 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/go-duration.rb +3 -0
- data/lib/go-duration/duration.rb +131 -0
- data/lib/go-duration/errors.rb +11 -0
- data/lib/go-duration/version.rb +3 -0
- data/spec/go-duration/duration_spec.rb +69 -0
- data/spec/spec_helper.rb +1 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae1bf552d2be8eba1d80e8f4a1b8fe0f3a3438e6
|
4
|
+
data.tar.gz: f2d4b5986aba2578496e8beb0756a0d5db18f651
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 957897604363254f46829038ddb0592cf64d3c420bd4bef9509ce518ecfd072ea70d500f3c9974ab6f8d8e9213796860fe34eeb537b8466cfdd13c34e655d6d4
|
7
|
+
data.tar.gz: cb45a0f85333bf80c0476cbd57318b28b972e94516cde13ff0d3303922a913cc5508bad5bd62aa8b1d3429bd1674d981ba50798d39304272e708c329e9bfa655
|
data/lib/go-duration.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
module GoDuration
|
2
|
+
# The base unit, a single nanosecond.
|
3
|
+
NANOSECOND = 1.freeze
|
4
|
+
|
5
|
+
# One microsecond in nanoseconds.
|
6
|
+
MICROSECOND = NANOSECOND << 10.freeze
|
7
|
+
|
8
|
+
# One millisecond in nanoseconds.
|
9
|
+
MILLISECOND = MICROSECOND << 1.freeze
|
10
|
+
|
11
|
+
# One second in nanoseconds.
|
12
|
+
SECOND = MILLISECOND << 1.freeze
|
13
|
+
|
14
|
+
# One minute in nanoseconds.
|
15
|
+
MINUTE = 60 * SECOND.freeze
|
16
|
+
|
17
|
+
# One hour in nanoseconds.
|
18
|
+
HOUR = 60 * MINUTE.freeze
|
19
|
+
|
20
|
+
# A mapping of Go's unit notations to their nanosecond values. Order is
|
21
|
+
# important, it defines how to_s works.
|
22
|
+
UNITS = {
|
23
|
+
h: HOUR,
|
24
|
+
m: MINUTE,
|
25
|
+
s: SECOND,
|
26
|
+
ms: MILLISECOND,
|
27
|
+
µs: MICROSECOND,
|
28
|
+
us: MICROSECOND,
|
29
|
+
ns: NANOSECOND,
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
# Duration deals with Golang's time.Duration. This type is commonly used
|
33
|
+
# in API's and/or CLI's, and is defined in the language itself (there is no
|
34
|
+
# formal specifcation or RFC for it). This class can be used to both parse
|
35
|
+
# and format duration strings.
|
36
|
+
class Duration
|
37
|
+
attr_reader :nanoseconds
|
38
|
+
|
39
|
+
# Initializes a new duration instance.
|
40
|
+
#
|
41
|
+
# @param number [Fixnum]
|
42
|
+
# @param unit [Symbol, :s]
|
43
|
+
#
|
44
|
+
# @return [Duration]
|
45
|
+
def initialize(number, unit: :s)
|
46
|
+
raise InvalidUnitError, unit unless UNITS[unit]
|
47
|
+
@nanoseconds = number * UNITS[unit]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the number of microseconds in the duration.
|
51
|
+
#
|
52
|
+
# @return [Fixnum]
|
53
|
+
def microseconds
|
54
|
+
nanoseconds / UNITS[:µs]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the number of milliseconds in the duration.
|
58
|
+
#
|
59
|
+
# @return [Fixnum]
|
60
|
+
def milliseconds
|
61
|
+
nanoseconds / UNITS[:ms]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the number of seconds in the duration.
|
65
|
+
#
|
66
|
+
# @return [Fixnum]
|
67
|
+
def seconds
|
68
|
+
nanoseconds / UNITS[:s]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the number of minutes in the duration.
|
72
|
+
#
|
73
|
+
# @return [Fixnum]
|
74
|
+
def minutes
|
75
|
+
nanoseconds / UNITS[:m]
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the number of hours in the duration.
|
79
|
+
#
|
80
|
+
# @return [Fixnum]
|
81
|
+
def hours
|
82
|
+
nanoseconds / UNITS[:h]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the exact duration in nanoseconds.
|
86
|
+
#
|
87
|
+
# @return [Fixnum]
|
88
|
+
def to_i
|
89
|
+
nanoseconds
|
90
|
+
end
|
91
|
+
|
92
|
+
# Formats the duration into a Go duration string.
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
def to_s
|
96
|
+
ns = nanoseconds
|
97
|
+
fmt = ""
|
98
|
+
|
99
|
+
UNITS.each do |unit, value|
|
100
|
+
number, ns = ns.divmod(value)
|
101
|
+
fmt << "#{number}#{unit}" if number > 0
|
102
|
+
end
|
103
|
+
|
104
|
+
fmt
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
module_function
|
109
|
+
|
110
|
+
# Parses a Go time.Duration string.
|
111
|
+
#
|
112
|
+
# @param duration [String] A Go duration string.
|
113
|
+
#
|
114
|
+
# @return [Duration]
|
115
|
+
def parse(duration)
|
116
|
+
ns = 0
|
117
|
+
|
118
|
+
until duration.empty?
|
119
|
+
number = duration.slice!(/^[[:digit:]]+/).to_i
|
120
|
+
unit = duration.slice!(/^[[:alpha:]]+/).to_sym
|
121
|
+
|
122
|
+
# Check that the units are recognized.
|
123
|
+
raise InvalidUnitError, unit unless UNITS[unit]
|
124
|
+
|
125
|
+
# Convert to nanoseconds and add to the total.
|
126
|
+
ns += (number * UNITS[unit])
|
127
|
+
end
|
128
|
+
|
129
|
+
Duration.new(ns, unit: :ns)
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module GoDuration
|
4
|
+
all_duration = "1h1m1s1ms1µs1ns"
|
5
|
+
all_nano = HOUR + MINUTE + SECOND + MILLISECOND + MICROSECOND + NANOSECOND
|
6
|
+
|
7
|
+
describe Duration do
|
8
|
+
describe "#new" do
|
9
|
+
it "creates from seconds by default" do
|
10
|
+
d = Duration.new(13)
|
11
|
+
expect(d.nanoseconds).to eq(13 * GoDuration::SECOND)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "creates with the provided unit" do
|
15
|
+
d = Duration.new(13, unit: :ms)
|
16
|
+
expect(d.nanoseconds).to eq(13 * GoDuration::MILLISECOND)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises an error on invalid unit" do
|
20
|
+
expect { Duration.new(1, unit: :nope) }
|
21
|
+
.to raise_error(GoDuration::InvalidUnitError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#to_s" do
|
26
|
+
context "when all units are present" do
|
27
|
+
it "renders all of the units" do
|
28
|
+
expect(Duration.new(all_nano, unit: :ns).to_s)
|
29
|
+
.to eq(all_duration)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when a unit overflows" do
|
34
|
+
it "reduces into a larger unit" do
|
35
|
+
expect(Duration.new(63, unit: :s).to_s).to eq("1m3s")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#parse" do
|
42
|
+
it "parses a time.Duration string" do
|
43
|
+
d = GoDuration.parse("1h")
|
44
|
+
expect(d.nanoseconds).to eq(HOUR)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "recognizes either form of microseconds" do
|
48
|
+
a = GoDuration.parse("99us").microseconds
|
49
|
+
b = GoDuration.parse("99µs").microseconds
|
50
|
+
expect(a).to eq(b)
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when multiple units are present" do
|
54
|
+
it "converts and adds them up" do
|
55
|
+
d = GoDuration.parse("1h43m")
|
56
|
+
expect(d.nanoseconds).to eq(HOUR + (43 * MINUTE))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "recognizes all of the units" do
|
60
|
+
d = GoDuration.parse(all_duration)
|
61
|
+
expect(d.nanoseconds).to eq(all_nano)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "raises an error if an invalid unit is found" do
|
65
|
+
expect { GoDuration.parse("1h2x") }.to raise_error(InvalidUnitError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'go-duration'
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: go-duration
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Uber
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-02-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: A parser and formatter for Golang's time.Duration
|
70
|
+
email:
|
71
|
+
- ru@ryanuber.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/go-duration.rb
|
77
|
+
- lib/go-duration/duration.rb
|
78
|
+
- lib/go-duration/errors.rb
|
79
|
+
- lib/go-duration/version.rb
|
80
|
+
- spec/go-duration/duration_spec.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
homepage: https://github.com/ryanuber/go-duration-ruby
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.5.1
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: A parser and formatter for Golang's time.Duration
|
106
|
+
test_files:
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/go-duration/duration_spec.rb
|