textrepo 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa38f5fbd3d1fd393eeb4ac200d1c051d8ff082cd92beaf0ab1b3756efd79e92
4
- data.tar.gz: 70107459347c9685f722a4aa2367c1f04ec3257c12c489a1436d242e2f322f4f
3
+ metadata.gz: e768443355f1c5764d5b5061f65c513485446f6df9ebce67b5b5f58a4ac30b20
4
+ data.tar.gz: 9062103447a89fd2e7484c448ac80315906a2602fba363e142c47f0d5ecc592d
5
5
  SHA512:
6
- metadata.gz: 19e12a6e1ac352a005aca887e887089a8daa8ae8fa0573e3d640803f19950747addd52ed77ddb9da9534f7b9596cc125917c9892ea2a14a031aaae33df753e01
7
- data.tar.gz: 3c304dbd6330719398ee377183ac26f29ffdfa89b279ff12fac795e9ad664e7b3b249c8f79d36e3bae215e7e114064dd01d3bb23b6652cd2147c8c09382d01ff
6
+ metadata.gz: 4889cfefdf5cadbaddd47f83e31a870829a9b144dddb346b8cf6f72d55fac68d6a75c1d7f180e315720f90eeb70801fd2a987920055c2d4334537955bd544678
7
+ data.tar.gz: 49c5b9a1d34de8335b815e7e56070d2fa9bfdaa2a9a931f53c93ac28bff6e3da03f307f57c5faf8155bf0c01ef7ee5a61956d0605cc7d372247f184da0b0c3a6
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
  ## [Unreleased]
8
8
  Nothing to record here.
9
9
 
10
+ ## [0.5.5] - 2020-11-10
11
+ ### Add
12
+ - Add more methods for `Timestamp` class.
13
+ - most of them are delegated to Time class
14
+ - some of them are useful to manipulate `Timestamp` object as
15
+ `String`.
16
+
10
17
  ## [0.5.4] - 2020-11-05
11
18
  ### Add
12
19
  - Add a feature for `Repository#update` to keep timestamp unchanged
@@ -22,15 +22,26 @@ module Textrepo
22
22
 
23
23
  # :stopdoc:
24
24
  module ErrMsg
25
- UNKNOWN_REPO_TYPE = 'unknown type for repository: %s'
26
- DUPLICATE_TIMESTAMP = 'duplicate timestamp: %s'
27
- EMPTY_TEXT = 'empty text'
28
- MISSING_TIMESTAMP = 'missing timestamp: %s'
25
+ ARGUMENT_RANGE = "argument out of range: %s"
26
+ UNKNOWN_REPO_TYPE = "unknown type for repository: %s"
27
+ DUPLICATE_TIMESTAMP = "duplicate timestamp: %s"
28
+ EMPTY_TEXT = "empty text"
29
+ MISSING_TIMESTAMP = "missing timestamp: %s"
29
30
  INVALID_TIMESTAMP_STRING = "invalid string as timestamp: %s"
30
31
  INVALID_SEARCH_RESULT = "invalid result by searcher: %s"
31
32
  end
32
33
  # :startdoc:
33
34
 
35
+ ##
36
+ # An error raised if argument is out of range for Timestamp class.
37
+
38
+ class ArgumentRangeError < Error
39
+ def initialize(arg)
40
+ super(ErrMsg::ARGUMENT_RANGE % arg)
41
+ end
42
+ end
43
+
44
+
34
45
  ##
35
46
  # An error raised if unknown type was specified as the repository
36
47
  # type.
@@ -1,3 +1,5 @@
1
+ require "forwardable"
2
+
1
3
  module Textrepo
2
4
  ##
3
5
  # Timestamp is generated from a Time object. It converts a time to
@@ -18,6 +20,7 @@ module Textrepo
18
20
 
19
21
  class Timestamp
20
22
  include Comparable
23
+ extend Forwardable
21
24
 
22
25
  ##
23
26
  # Time object which generates the Timestamp object.
@@ -29,16 +32,28 @@ module Textrepo
29
32
 
30
33
  attr_reader :suffix
31
34
 
35
+ ##
36
+ # String object which is regarded as a value of Timestamp object.
37
+ # The value is generated from @time and @suffix.
38
+
39
+ attr_reader :str
40
+
32
41
  ##
33
42
  # Creates a Timestamp object from a Time object. In addition, an
34
43
  # Integer can be passed as a suffix use.
35
44
  #
45
+ # Since Textrepo adapts 1 second as the time resolution, the
46
+ # subsec part of a given time will be ignored.
47
+ #
36
48
  # :call-seq:
37
49
  # new(Time, Integer = nil) -> Timestamp
38
50
 
39
51
  def initialize(time, suffix = nil)
40
- @time = time
52
+ raise ArgumentRangeError, suffix unless is_valid_suffix?(suffix)
53
+ parts = [:year, :mon, :day, :hour, :min, :sec].map{ |s| time.send(s) }
54
+ @time = Time.new(*parts)
41
55
  @suffix = suffix
56
+ @str = time_to_str(@time, @suffix)
42
57
  end
43
58
 
44
59
  def <=>(other) # :nodoc:
@@ -51,19 +66,257 @@ module Textrepo
51
66
  end
52
67
 
53
68
  ##
54
- # Generate an obvious time string.
69
+ # Generates an obvious time string.
55
70
  #
56
71
  # %Y %m %d %H %M %S suffix
57
72
  # "2020-12-30 12:34:56 (0 | nil)" -> "20201230123456"
58
73
  # "2020-12-30 12:34:56 (7)" -> "20201230123456_007"
59
74
 
60
75
  def to_s
76
+ @str
77
+ end
78
+
79
+ alias to_str to_s
80
+
81
+ # :stopdoc:
82
+
83
+ # delegators to Time object
84
+
85
+ def_instance_delegators :@time, :year, :mon, :day, :hour, :min, :sec
86
+ def_instance_delegators :@time, :wday, :monday?, :tuesday?, :wednesday?, :thursday?, :friday?, :saturday?, :sunday?
87
+ def_instance_delegators :@time, :asctime, :ctime, :strftime
88
+ def_instance_delegators :@time, :subsec, :nsec, :usec
89
+ def_instance_delegators :@time, :tv_nsec, :tv_sec, :tv_usec
90
+ def_instance_delegators :@time, :to_f, :to_i, :to_r
91
+ def_instance_delegators :@time, :yday, :mday
92
+ def_instance_delegators :@time, :month
93
+
94
+ # :startdoc:
95
+
96
+ def hash # :nodoc:
97
+ @str[0, 14].to_i * 1000 + @suffix.to_i
98
+ end
99
+
100
+ def eql?(other) # :nodoc:
101
+ other.is_a?(Timestamp) && @time == other.time && @suffix == other.suffix
102
+ end
103
+
104
+ ##
105
+ # Returns a new Timestamp object which is given seconds ahead.
106
+ # Even if the suffix is not nil, the new Timestamp object will
107
+ # always have nil as its suffix.
108
+ #
109
+ # :call-seq:
110
+ # +(Integer) -> Timestamp
111
+
112
+ def +(seconds)
113
+ Timestamp.new(@time + seconds, nil)
114
+ end
115
+
116
+ ##
117
+ # Returns difference of seconds between self and an argument. If
118
+ # the argument is an Integer object, returns a new Timestamp
119
+ # object which is the given seconds behind.
120
+ #
121
+ # Even if the suffix is not nil, the new Timestamp object will
122
+ # always have nil as its suffix.
123
+ #
124
+ # :call-seq:
125
+ # -(Time) -> Float
126
+ # -(Timetamp) -> Float
127
+ # -(Integer) -> Timestamp
128
+
129
+ def -(arg)
130
+ case arg
131
+ when Time
132
+ @time - arg
133
+ when Timestamp
134
+ @time - arg.time
135
+ when Integer
136
+ Timestamp.new(@time - arg, nil)
137
+ when NilClass
138
+ raise TypeError, "can't convert nil into an exact number"
139
+ else
140
+ raise ArgumentError, arg
141
+ end
142
+ end
143
+
144
+ ##
145
+ # Generates an array contains components of the Timestamp object.
146
+ # Components means "year", "mon", "day", "hour", "min", "sec", and
147
+ # "suffix".
148
+
149
+ def to_a
150
+ a = [:year, :mon, :day, :hour, :min, :sec, :suffix].map { |s| self.send(s) }
151
+ a.delete_at(-1) if a[-1].nil?
152
+ a
153
+ end
154
+
155
+ # :stopdoc:
156
+
157
+ # delegators to String object
158
+
159
+ def_instance_delegators :@str, :size, :length
160
+ def_instance_delegators :@str, :include?, :match, :match?
161
+
162
+ # :startdoc:
163
+
164
+ ##
165
+ # Returns a character or sub-string specified with args.
166
+ #
167
+ # Following type of objects could be used as args:
168
+ #
169
+ # - Integer : specifies an index
170
+ # - Integer, Integer : specified an start index and length of sub-string
171
+ # - Range : specified range of sub-string
172
+ # - Symbol : specified a type of part
173
+ #
174
+ # Following symbols could be specified:
175
+ #
176
+ # - :year
177
+ # - :mon, or :month
178
+ # - :day
179
+ # - :hour
180
+ # - :min
181
+ # - :sec
182
+ # - :suffix
183
+ #
184
+ # :call-seq:
185
+ # self[nth as Integer] -> String | nil
186
+ # self[nth as Integer, len as Integer] -> String | nil
187
+ # self[range as Range] -> String
188
+ # self[symbol as Symbol] -> String
189
+
190
+ def [](*args)
191
+ raise ArgumentError, "wrong number of arguments (given %s, execpted 1..2)" % args.size unless (1..2).include?(args.size)
192
+
193
+ arg = args[0]
194
+ case arg
195
+ when Symbol, String
196
+ key = arg.to_sym
197
+ if key == :suffix
198
+ @suffix.nil? ? nil : FMTSTRS[key] % @suffix
199
+ elsif FMTSTRS.keys.include?(key)
200
+ @time.strftime(FMTSTRS[key])
201
+ else
202
+ nil
203
+ end
204
+ else
205
+ @str[*args]
206
+ end
207
+ end
208
+
209
+ alias slice []
210
+
211
+ ##
212
+ # Returns a Timestamp object which has a next Time object.
213
+ #
214
+ # If true was passed as an argument, use incremented suffix as
215
+ # base instead of a next Time object.
216
+ #
217
+ # For example,
218
+ #
219
+ # "20201110160100" -> "20201110160101" (false as arg)
220
+ # "20201110160100" -> "20201110160100_001" (true as arg)
221
+ # "20201110160200_001" -> "20201110160201" (false as arg)
222
+ # "20201110160200_001" -> "20201110160200_002" (true as arg)
223
+ #
224
+ # If suffix was 999 before call this method, raises
225
+ # ArgumentRangeError.
226
+
227
+ def next(use_suffix = nil)
228
+ if use_suffix
229
+ Timestamp.new(@time, increase_suffix(@suffix.to_i, 1))
230
+ else
231
+ Timestamp.new(@time + 1, nil)
232
+ end
233
+ end
234
+
235
+ alias succ next
236
+
237
+ ##
238
+ # Updates the time value to a next Time destructively. See the
239
+ # document for Timestamp#next for more details.
240
+ #
241
+ # If suffix was 999 before call this method, raises
242
+ # ArgumentRangeError.
243
+
244
+ def next!(use_suffix = nil)
245
+ if use_suffix
246
+ @suffix = increase_suffix(@suffix.to_i, 1)
247
+ else
248
+ @time += 1
249
+ @suffix = nil
250
+ end
251
+ @str = time_to_str(@time, @suffix)
252
+ self
253
+ end
254
+
255
+ alias succ! next!
256
+
257
+ ##
258
+ # Splits the timestamp string into array of time parts, such as
259
+ # year, month, day, hour, minute, and second. Then, returns the
260
+ # array.
261
+ #
262
+ # When a block was passed, it would apply to each part of the
263
+ # array. Then, returns self.
264
+
265
+ def split(_ = $;, _ = 0, &blk)
266
+ parts = Timestamp.split_stamp(@str)
267
+ if blk.nil?
268
+ parts
269
+ else
270
+ parts.each { |p| yield p }
271
+ self
272
+ end
273
+ end
274
+
275
+ # :stopdoc:
276
+
277
+ def initialize_copy(_)
278
+ @time = @time.dup
279
+ @suffix = @suffix
280
+ @str = @str.dup
281
+ end
282
+
283
+ def freeze; @time.freeze; @suffix.freeze; @str.freeze; end
284
+ def taint; @time.taint; @suffix.taint; @str.taint; end
285
+ def untaint; @time.untaint; @suffix.untaint; @str.untaint; end
286
+
287
+ private
288
+
289
+ def is_valid_suffix?(suffix)
290
+ suffix.nil? || (0..999).include?(suffix)
291
+ end
292
+
293
+ def increase_suffix(suffix, num)
294
+ increased = suffix + num
295
+ raise ArgumentRangeError, suffix unless is_valid_suffix?(increased)
296
+ increased
297
+ end
298
+
299
+ def time_to_str(time, suffix = nil)
61
300
  s = @time.strftime("%Y%m%d%H%M%S")
62
301
  s += "_#{"%03u" % @suffix}" unless @suffix.nil? || @suffix == 0
63
302
  s
64
303
  end
65
304
 
305
+ FMTSTRS = {
306
+ :year => "%Y", :mon => "%m", :month => "%m", :day => "%d",
307
+ :hour => "%H", :min => "%M", :sec => "%S", :suffix => "%03u",
308
+ }
309
+
310
+ # :startdoc:
66
311
  class << self
312
+
313
+ ##
314
+ # Returns a Timestamp object generated from the current time.
315
+
316
+ def now(suffix = nil)
317
+ Timestamp.new(Time.now, suffix)
318
+ end
319
+
67
320
  ##
68
321
  # Splits a string which represents a timestamp into components.
69
322
  # Each component represents a part of constructs to instantiate
@@ -79,7 +332,8 @@ module Textrepo
79
332
  raise InvalidTimestampStringError, stamp_str if stamp_str.nil?
80
333
  # yyyy mo dd hh mi ss sfx
81
334
  a = [0..3, 4..5, 6..7, 8..9, 10..11, 12..13, 15..17].map {|r| stamp_str[r]}
82
- a[-1].nil? ? a[0..-2] : a
335
+ a.delete_at(-1) if a[-1].nil?
336
+ a
83
337
  end
84
338
 
85
339
  ##
@@ -108,7 +362,7 @@ module Textrepo
108
362
  raise InvalidTimestampStringError, emsg
109
363
  end
110
364
  end
111
-
112
365
  end
366
+
113
367
  end
114
368
  end
@@ -1,3 +1,3 @@
1
1
  module Textrepo
2
- VERSION = '0.5.4'
2
+ VERSION = '0.5.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textrepo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - mnbi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-05 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler