go-duration 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|