nrser 0.3.1 → 0.3.2
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 +4 -4
- data/lib/nrser/core_ext/string.rb +6 -4
- data/lib/nrser/errors/conflict_error.rb +23 -0
- data/lib/nrser/errors.rb +1 -5
- data/lib/nrser/functions/string.rb +0 -53
- data/lib/nrser/log/formatters/color.rb +1 -1
- data/lib/nrser/log/mixin.rb +57 -3
- data/lib/nrser/log.rb +12 -2
- data/lib/nrser/props/class_methods.rb +29 -2
- data/lib/nrser/props/immutable/hash.rb +4 -3
- data/lib/nrser/props/metadata.rb +35 -3
- data/lib/nrser/props/prop.rb +75 -15
- data/lib/nrser/refinements/types.rb +4 -0
- data/lib/nrser/types/arrays.rb +3 -0
- data/lib/nrser/types/hashes.rb +4 -1
- data/lib/nrser/types/paths.rb +15 -0
- data/lib/nrser/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c1aebae949432774359be83991d38a1f2401011
|
4
|
+
data.tar.gz: 4c30490c2fd5fdab98b488e20a1fbc3a1b7b6273
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d57b3ce6c67e7bc25834d9109c290a86c64a56798c47ed23b3f01ca2ce3011ea90263cf3785fa6f76a3db00d14c2c9d04595e7fa1f35006f87cbaffebad823c
|
7
|
+
data.tar.gz: fbd33e894a99dadbe17b8dbc7569607871e829c161518e20f0f6eb7bcea537856a1a3a9d85edcd7b7a004be01ec1928b098bfac4f332913332cd059b329c7904
|
@@ -21,12 +21,14 @@ class String
|
|
21
21
|
end
|
22
22
|
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
NRSER.constantize self
|
24
|
+
def to_const
|
25
|
+
safe_constantize
|
27
26
|
end
|
28
27
|
|
29
|
-
|
28
|
+
|
29
|
+
def to_const!
|
30
|
+
constantize
|
31
|
+
end
|
30
32
|
|
31
33
|
|
32
34
|
# @return [Pathname]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require_relative './nicer_error'
|
11
|
+
|
12
|
+
|
13
|
+
# Definitions
|
14
|
+
# =======================================================================
|
15
|
+
|
16
|
+
# General error for raising when something conflicts with something else -
|
17
|
+
# it's not the type or an argument, but something about the data or
|
18
|
+
# configuration just isn't ok.
|
19
|
+
#
|
20
|
+
module NRSER
|
21
|
+
class ConflictError < ::StandardError
|
22
|
+
include NRSER::NicerError
|
23
|
+
end; end # class NRSER::ConflictError
|
data/lib/nrser/errors.rb
CHANGED
@@ -16,15 +16,11 @@ require_relative './errors/count_error'
|
|
16
16
|
require_relative './errors/argument_error'
|
17
17
|
require_relative './errors/type_error'
|
18
18
|
require_relative './errors/abstract_method_error'
|
19
|
+
require_relative './errors/conflict_error'
|
19
20
|
|
20
21
|
|
21
22
|
module NRSER
|
22
23
|
|
23
|
-
# Indicates some piece of application state is in conflict with the attempted
|
24
|
-
# operation.
|
25
|
-
class ConflictError < StandardError; end
|
26
|
-
|
27
|
-
|
28
24
|
# A wrapper error around a list of other errors.
|
29
25
|
#
|
30
26
|
class MultipleErrors < StandardError
|
@@ -233,59 +233,6 @@ module NRSER
|
|
233
233
|
|
234
234
|
end # .smart_ellipsis
|
235
235
|
|
236
|
-
|
237
|
-
# Get the constant identified by a string.
|
238
|
-
#
|
239
|
-
# @pure Return value depends only on parameters.
|
240
|
-
#
|
241
|
-
# @example
|
242
|
-
#
|
243
|
-
# SomeClass == NRSER.constantize(SomeClass.name)
|
244
|
-
#
|
245
|
-
# Lifted from ActiveSupport.
|
246
|
-
#
|
247
|
-
# @param [String] camel_cased_word
|
248
|
-
# The constant's camel-cased, double-colon-separated "name",
|
249
|
-
# like "NRSER::Types::Array".
|
250
|
-
#
|
251
|
-
# @return [Object]
|
252
|
-
#
|
253
|
-
# @raise [NameError]
|
254
|
-
# When the name is not in CamelCase or is not initialized.
|
255
|
-
#
|
256
|
-
def self.constantize(camel_cased_word)
|
257
|
-
names = camel_cased_word.split('::')
|
258
|
-
|
259
|
-
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
260
|
-
Object.const_get(camel_cased_word) if names.empty?
|
261
|
-
|
262
|
-
# Remove the first blank element in case of '::ClassName' notation.
|
263
|
-
names.shift if names.size > 1 && names.first.empty?
|
264
|
-
|
265
|
-
names.inject(Object) do |constant, name|
|
266
|
-
if constant == Object
|
267
|
-
constant.const_get(name)
|
268
|
-
else
|
269
|
-
candidate = constant.const_get(name)
|
270
|
-
next candidate if constant.const_defined?(name, false)
|
271
|
-
next candidate unless Object.const_defined?(name)
|
272
|
-
|
273
|
-
# Go down the ancestors to check if it is owned directly. The check
|
274
|
-
# stops when we reach Object or the end of ancestors tree.
|
275
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
276
|
-
break const if ancestor == Object
|
277
|
-
break ancestor if ancestor.const_defined?(name, false)
|
278
|
-
const
|
279
|
-
end
|
280
|
-
|
281
|
-
# owner is in Object, so raise
|
282
|
-
constant.const_get(name, false)
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end # .constantize
|
286
|
-
|
287
|
-
singleton_class.send :alias_method, :to_const, :constantize
|
288
|
-
|
289
236
|
# @!endgroup String Functions
|
290
237
|
|
291
238
|
end # module NRSER
|
@@ -98,7 +98,7 @@ class NRSER::Log::Formatters::Color < ::SemanticLogger::Formatters::Color
|
|
98
98
|
# ======================================================================
|
99
99
|
|
100
100
|
# Instantiate a new `ColorFormatter`.
|
101
|
-
def initialize ap: {multiline: true, raw: true},
|
101
|
+
def initialize ap: {multiline: true }, # raw: true},
|
102
102
|
color_map: self.class.default_color_map,
|
103
103
|
time_format: ::SemanticLogger::Formatters::Base::TIME_FORMAT,
|
104
104
|
log_host: false,
|
data/lib/nrser/log/mixin.rb
CHANGED
@@ -16,15 +16,26 @@ module NRSER::Log::Mixin
|
|
16
16
|
# Methods to mix into the including class.
|
17
17
|
#
|
18
18
|
module ClassMethods
|
19
|
+
|
20
|
+
protected
|
21
|
+
# ========================================================================
|
22
|
+
|
23
|
+
def create_logger
|
24
|
+
NRSER::Log[self]
|
25
|
+
end
|
26
|
+
|
27
|
+
public # end protected ***************************************************
|
28
|
+
|
19
29
|
# Returns [SemanticLogger::Logger] class level logger
|
20
30
|
def logger
|
21
|
-
@semantic_logger ||=
|
31
|
+
@semantic_logger ||= create_logger
|
22
32
|
end
|
23
33
|
|
24
34
|
# Replace instance class level logger
|
25
35
|
def logger= logger
|
26
36
|
@semantic_logger = logger
|
27
37
|
end
|
38
|
+
|
28
39
|
end
|
29
40
|
|
30
41
|
|
@@ -42,9 +53,52 @@ module NRSER::Log::Mixin
|
|
42
53
|
# Instance Methods
|
43
54
|
# ========================================================================
|
44
55
|
|
45
|
-
#
|
56
|
+
# Gets the {NRSER::Log:Logger} for use in the instance. This will be the
|
57
|
+
# class logger from {ClassMethods#logger} unless the instance has a
|
58
|
+
# `#create_logger` method.
|
59
|
+
#
|
60
|
+
# The `#create_logger` method is expected to return a {NRSER::Log::Logger}
|
61
|
+
# instance, which will be saved in the `@semantic_logger` instance variable
|
62
|
+
# for future use.
|
63
|
+
#
|
64
|
+
# That method does not need to return a different logger for every instance
|
65
|
+
# - if you just want to have a different logger for *all* instance with a
|
66
|
+
# different level or formatter or whatever, you can save it somewhere else
|
67
|
+
# and always return that same instance.
|
68
|
+
#
|
69
|
+
# If you are dealing with frozen instances make sure to call `#logger` before
|
70
|
+
# you freeze (likely in the constructor). If you don't want to save the
|
71
|
+
# logger at all, just override this method itself.
|
72
|
+
#
|
73
|
+
# This is a departure from {SemanticLogger::Loggable} that started because
|
74
|
+
# if the instance is frozen then attempting to set `@semantic_logger` will
|
75
|
+
# raise an error.
|
76
|
+
#
|
77
|
+
# I also started ending up with classes that wanted to individually
|
78
|
+
# configure their loggers, so it seemed like we could take out two birds
|
79
|
+
# with this stone.
|
80
|
+
#
|
81
|
+
# @return [SemanticLogger::Logger]
|
82
|
+
# Instance level logger, if {ClassMethods.instance_logger?},
|
83
|
+
# otherwise the class level logger from {ClassMethods#logger}.
|
84
|
+
#
|
46
85
|
def logger
|
47
|
-
@semantic_logger
|
86
|
+
return @semantic_logger if @semantic_logger
|
87
|
+
|
88
|
+
if respond_to?( :create_logger, true )
|
89
|
+
@semantic_logger = begin
|
90
|
+
create_logger
|
91
|
+
rescue Exception => error
|
92
|
+
self.class.logger.warn \
|
93
|
+
"Error creating instance logger",
|
94
|
+
{ instance: self.inspect },
|
95
|
+
error
|
96
|
+
|
97
|
+
self.class.logger
|
98
|
+
end
|
99
|
+
else
|
100
|
+
self.class.logger
|
101
|
+
end
|
48
102
|
end
|
49
103
|
|
50
104
|
|
data/lib/nrser/log.rb
CHANGED
@@ -88,7 +88,7 @@ module NRSER::Log
|
|
88
88
|
# Class Methods
|
89
89
|
# ========================================================================
|
90
90
|
|
91
|
-
def self.
|
91
|
+
def self.logger_for subject
|
92
92
|
# key = logger_type_and_name_from subject
|
93
93
|
#
|
94
94
|
# if @__loggers__.key? key
|
@@ -100,6 +100,9 @@ module NRSER::Log
|
|
100
100
|
instance = NRSER::Log::Logger.new subject
|
101
101
|
end
|
102
102
|
|
103
|
+
singleton_class.send :alias_method, :[], :logger_for
|
104
|
+
|
105
|
+
|
103
106
|
|
104
107
|
# @!group Utility Class Methods
|
105
108
|
# ------------------------------------------------------------------------
|
@@ -560,9 +563,16 @@ module NRSER::Log
|
|
560
563
|
end
|
561
564
|
|
562
565
|
if will_say_hi
|
566
|
+
loggable_dest = case dest
|
567
|
+
when Hash
|
568
|
+
dest.map { |k, v| [ k, v.to_s.truncate( 42 ) ] }.to_h
|
569
|
+
else
|
570
|
+
dest.to_s.truncate 42
|
571
|
+
end
|
572
|
+
|
563
573
|
logger.info "Hi! Logging is setup",
|
564
574
|
level: self.level,
|
565
|
-
dest:
|
575
|
+
dest: loggable_dest,
|
566
576
|
sync: sync
|
567
577
|
end
|
568
578
|
|
@@ -62,6 +62,15 @@ module NRSER::Props::ClassMethods
|
|
62
62
|
end
|
63
63
|
|
64
64
|
|
65
|
+
def prop_for name_or_alias, *props_args
|
66
|
+
sym = name_or_alias.to_sym
|
67
|
+
|
68
|
+
props( *props_args ).each_value.find { |prop|
|
69
|
+
prop.name == sym || prop.aliases.include?( sym )
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
|
65
74
|
def invariants *args, &block
|
66
75
|
metadata.invariants *args, &block
|
67
76
|
end
|
@@ -89,7 +98,6 @@ module NRSER::Props::ClassMethods
|
|
89
98
|
#
|
90
99
|
def from_data data
|
91
100
|
values = {}
|
92
|
-
props = self.props
|
93
101
|
|
94
102
|
unless data.respond_to? :each_pair
|
95
103
|
raise NRSER::ArgumentError.new \
|
@@ -107,7 +115,7 @@ module NRSER::Props::ClassMethods
|
|
107
115
|
end
|
108
116
|
|
109
117
|
if prop_key &&
|
110
|
-
(prop =
|
118
|
+
(prop = prop_for( prop_key, only_primary: true ))
|
111
119
|
values[prop_key] = prop.value_from_data data_value
|
112
120
|
end
|
113
121
|
end
|
@@ -115,4 +123,23 @@ module NRSER::Props::ClassMethods
|
|
115
123
|
self.new values
|
116
124
|
end # #from_data
|
117
125
|
|
126
|
+
|
127
|
+
# Get an instance from a source.
|
128
|
+
#
|
129
|
+
# @experimental
|
130
|
+
#
|
131
|
+
# @param [self | String | Hash] source
|
132
|
+
# @return [self]
|
133
|
+
#
|
134
|
+
def self.from source
|
135
|
+
return source if source.is_a?( self )
|
136
|
+
return from_s( source ) if source.is_a?( String )
|
137
|
+
return from_data( source ) if source.respond_to?( :each_pair )
|
138
|
+
return from_data( source.to_h ) if source.respond_to?( :to_h )
|
139
|
+
|
140
|
+
raise NRSER::ArgumentError.new \
|
141
|
+
"Unable to load #{ self } from source",
|
142
|
+
source: source
|
143
|
+
end # .from
|
144
|
+
|
118
145
|
end # module NRSER::Props::ClassMethods
|
@@ -95,9 +95,10 @@ module NRSER::Props::Immutable::Hash
|
|
95
95
|
|
96
96
|
super_values = {}
|
97
97
|
|
98
|
-
self.class.metadata.
|
99
|
-
|
100
|
-
|
98
|
+
self.class.metadata.
|
99
|
+
each_primary_prop_value_from( values ) { |prop, value|
|
100
|
+
super_values[prop.name] = value
|
101
|
+
}
|
101
102
|
|
102
103
|
super super_values
|
103
104
|
|
data/lib/nrser/props/metadata.rb
CHANGED
@@ -38,6 +38,12 @@ class NRSER::Props::Metadata
|
|
38
38
|
VARIABLE_NAME = :@__NRSER_metadata__
|
39
39
|
|
40
40
|
|
41
|
+
# Mixins
|
42
|
+
# ========================================================================
|
43
|
+
|
44
|
+
include NRSER::Log::Mixin
|
45
|
+
|
46
|
+
|
41
47
|
# Class Methods
|
42
48
|
# ======================================================================
|
43
49
|
|
@@ -217,6 +223,24 @@ class NRSER::Props::Metadata
|
|
217
223
|
def each_primary_prop_value_from values, &block
|
218
224
|
primary_props = props only_primary: true
|
219
225
|
|
226
|
+
props_by_names_and_aliases = {}
|
227
|
+
primary_props.each_value do |prop|
|
228
|
+
[prop.name, *prop.aliases].each do |sym|
|
229
|
+
if props_by_names_and_aliases.key? sym
|
230
|
+
other_prop = props_by_names_and_aliases[sym]
|
231
|
+
|
232
|
+
prop_sym_is = sym == prop.name ? 'name' : 'alias'
|
233
|
+
other_prop_sym_is = sym == other_prop.name ? 'name' : 'alias'
|
234
|
+
|
235
|
+
raise NRSER::ConflictError.new \
|
236
|
+
"Prop", prop.to_desc, prop_sym_is, sym.inspect,
|
237
|
+
"conflicts with", other_prop.to_desc, "of", other_prop_sym_is
|
238
|
+
end
|
239
|
+
|
240
|
+
props_by_names_and_aliases[sym] = prop
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
220
244
|
# Normalize values to a `Hash<Symbol, VALUE>` so everything can deal with
|
221
245
|
# one form. Default values will be set here as they're resolved and made
|
222
246
|
# available to subsequent {Prop#default} calls.
|
@@ -237,9 +261,9 @@ class NRSER::Props::Metadata
|
|
237
261
|
# If the `name` corresponds to a primary prop set it in the values by
|
238
262
|
# name
|
239
263
|
#
|
240
|
-
|
241
|
-
|
242
|
-
|
264
|
+
if props_by_names_and_aliases.key? name
|
265
|
+
values_by_name[ props_by_names_and_aliases[name].name ] = value
|
266
|
+
end
|
243
267
|
}
|
244
268
|
elsif values.respond_to? :each_index
|
245
269
|
indexed = []
|
@@ -263,6 +287,14 @@ class NRSER::Props::Metadata
|
|
263
287
|
END
|
264
288
|
end
|
265
289
|
|
290
|
+
# Way to noisy, even for trace
|
291
|
+
# logger.trace "Ready to start loading values",
|
292
|
+
# values: values,
|
293
|
+
# values_by_name: values_by_name,
|
294
|
+
# props_by_names_and_aliases: props_by_names_and_aliases.map { |k, v|
|
295
|
+
# [ k, v.to_desc ]
|
296
|
+
# }.to_h
|
297
|
+
|
266
298
|
# Topological sort the primary props by their default dependencies.
|
267
299
|
#
|
268
300
|
NRSER::Graph::TSorter.new(
|
data/lib/nrser/props/prop.rb
CHANGED
@@ -18,11 +18,11 @@ require 'nrser/refinements/types'
|
|
18
18
|
using NRSER::Types
|
19
19
|
|
20
20
|
|
21
|
-
#
|
21
|
+
# Namespace
|
22
22
|
# =======================================================================
|
23
23
|
|
24
|
-
module NRSER
|
25
|
-
module
|
24
|
+
module NRSER
|
25
|
+
module Props
|
26
26
|
|
27
27
|
|
28
28
|
# Definitions
|
@@ -33,10 +33,17 @@ module NRSER::Props; end
|
|
33
33
|
#
|
34
34
|
# Props are immutable by design.
|
35
35
|
#
|
36
|
-
class
|
36
|
+
class Prop
|
37
|
+
|
38
|
+
# Mixins
|
39
|
+
# ========================================================================
|
37
40
|
|
38
41
|
include NRSER::Log::Mixin
|
39
42
|
|
43
|
+
|
44
|
+
# Attributes
|
45
|
+
# ========================================================================
|
46
|
+
|
40
47
|
# The class the prop was defined in.
|
41
48
|
#
|
42
49
|
# @return [Class]
|
@@ -154,8 +161,17 @@ class NRSER::Props::Prop
|
|
154
161
|
@to_data = to_data
|
155
162
|
@from_data = from_data
|
156
163
|
|
157
|
-
@reader =
|
158
|
-
|
164
|
+
@reader, @writer = [ reader, writer ].map do |value|
|
165
|
+
t.match value,
|
166
|
+
t.bool?,
|
167
|
+
value,
|
168
|
+
|
169
|
+
t.hash_( keys: t.sym, values: t.bool ),
|
170
|
+
:freeze.to_proc,
|
171
|
+
|
172
|
+
t.hash_( keys: t.label, values: t.bool ),
|
173
|
+
->( hash ) { hash.map { |k, v| [ k.to_sym, v ] }.to_h.freeze }
|
174
|
+
end
|
159
175
|
|
160
176
|
@aliases = t.array( t.sym ).check! aliases
|
161
177
|
|
@@ -201,7 +217,7 @@ class NRSER::Props::Prop
|
|
201
217
|
defaults don't make any sense.
|
202
218
|
|
203
219
|
Attempted to construct prop <%= name.inspect %> for class
|
204
|
-
{<%=
|
220
|
+
{<%= defined_in_name %>} with:
|
205
221
|
|
206
222
|
default:
|
207
223
|
|
@@ -267,7 +283,7 @@ class NRSER::Props::Prop
|
|
267
283
|
<%= default.pretty_inspect %>
|
268
284
|
|
269
285
|
when constructing prop <%= name.inspect %>
|
270
|
-
for class <%=
|
286
|
+
for class <%= defined_in_name %>
|
271
287
|
END
|
272
288
|
end
|
273
289
|
|
@@ -290,12 +306,27 @@ class NRSER::Props::Prop
|
|
290
306
|
# Used by the {NRSER::Props::Props::ClassMethods.prop} "macro" method to
|
291
307
|
# determine if it should create a reader method on the propertied class.
|
292
308
|
#
|
309
|
+
# @param [Symbol] name
|
310
|
+
# The prop name or alias in question.
|
311
|
+
#
|
293
312
|
# @return [Boolean]
|
294
313
|
# `true` if a reader method should be created for the prop value.
|
295
314
|
#
|
296
315
|
def create_reader? name
|
297
|
-
|
298
|
-
|
316
|
+
t.sym.check! name
|
317
|
+
|
318
|
+
# If the options was explicitly provided then use that
|
319
|
+
case @reader
|
320
|
+
when nil
|
321
|
+
# Fall through
|
322
|
+
when Hash
|
323
|
+
return @reader[name] if @reader.key? name
|
324
|
+
# else fall through
|
325
|
+
when true, false
|
326
|
+
return @reader
|
327
|
+
end
|
328
|
+
|
329
|
+
# return @reader unless @reader.nil?
|
299
330
|
|
300
331
|
# Always create readers for primary props
|
301
332
|
return true if primary?
|
@@ -321,7 +352,16 @@ class NRSER::Props::Prop
|
|
321
352
|
# Always `false` for the moment.
|
322
353
|
#
|
323
354
|
def create_writer? name
|
324
|
-
|
355
|
+
# If the options was explicitly provided then use that
|
356
|
+
case @writer
|
357
|
+
when nil
|
358
|
+
# Fall through
|
359
|
+
when Hash
|
360
|
+
return @writer[name] if @writer.key? name
|
361
|
+
# else fall through
|
362
|
+
when true, false
|
363
|
+
return @writer
|
364
|
+
end
|
325
365
|
|
326
366
|
storage_immutable = defined_in.metadata.storage.try( :immutable? )
|
327
367
|
|
@@ -331,6 +371,12 @@ class NRSER::Props::Prop
|
|
331
371
|
end # #create_writer?
|
332
372
|
|
333
373
|
|
374
|
+
def defined_in_name
|
375
|
+
return defined_in.safe_name if defined_in.respond_to?( :safe_name )
|
376
|
+
defined_in.to_s
|
377
|
+
end
|
378
|
+
|
379
|
+
|
334
380
|
# Full name with class prop was defined in.
|
335
381
|
#
|
336
382
|
# @example
|
@@ -340,7 +386,7 @@ class NRSER::Props::Prop
|
|
340
386
|
# @return [String]
|
341
387
|
#
|
342
388
|
def full_name
|
343
|
-
"#{
|
389
|
+
"#{ defined_in_name }##{ name }"
|
344
390
|
end # #full_name
|
345
391
|
|
346
392
|
|
@@ -616,7 +662,9 @@ class NRSER::Props::Prop
|
|
616
662
|
# This {Prop} does not have any custom `from_data` instructions, which
|
617
663
|
# means we must rely on the {#type} to covert *data* to a *value*.
|
618
664
|
#
|
619
|
-
if type.
|
665
|
+
if data.is_a?( String ) && type.has_from_s?
|
666
|
+
type.from_s data
|
667
|
+
elsif type.has_from_data?
|
620
668
|
type.from_data data
|
621
669
|
else
|
622
670
|
data
|
@@ -660,11 +708,23 @@ class NRSER::Props::Prop
|
|
660
708
|
end # #value_from_data
|
661
709
|
|
662
710
|
|
711
|
+
def to_desc
|
712
|
+
"#{ full_name }:#{ type }"
|
713
|
+
end
|
714
|
+
|
715
|
+
|
663
716
|
# @return [String]
|
664
717
|
# a short string describing the instance.
|
665
718
|
#
|
666
719
|
def to_s
|
667
|
-
"#<#{ self.class.safe_name } #{
|
720
|
+
"#<#{ self.class.safe_name } #{ to_desc }>"
|
668
721
|
end # #to_s
|
669
722
|
|
670
|
-
end # class
|
723
|
+
end # class Prop
|
724
|
+
|
725
|
+
|
726
|
+
# /Namespace
|
727
|
+
# =======================================================================
|
728
|
+
|
729
|
+
end # module Props
|
730
|
+
end # module NRSER
|
data/lib/nrser/types/arrays.rb
CHANGED
data/lib/nrser/types/hashes.rb
CHANGED
@@ -191,9 +191,12 @@ module NRSER::Types
|
|
191
191
|
# @return [NRSER::Types::Type]
|
192
192
|
# Newly constructed hash type from `args`.
|
193
193
|
#
|
194
|
+
# @todo
|
195
|
+
# Make `map` into it's own looser interface for "hash-like" object API.
|
196
|
+
#
|
194
197
|
def_factory(
|
195
198
|
:hash_type,
|
196
|
-
aliases: [ :dict, :hash_ ]
|
199
|
+
aliases: [ :dict, :hash_, :map ]
|
197
200
|
) do |**kwds|
|
198
201
|
if kwds.key?( :keys ) || kwds.key?( :values )
|
199
202
|
HashOfType.new **kwds
|
data/lib/nrser/types/paths.rb
CHANGED
@@ -85,6 +85,21 @@ module NRSER::Types
|
|
85
85
|
end
|
86
86
|
|
87
87
|
|
88
|
+
# A relative path.
|
89
|
+
#
|
90
|
+
# @todo
|
91
|
+
# Quick addition, not sure if it's totally right with regard to tilde
|
92
|
+
# paths and such.
|
93
|
+
#
|
94
|
+
def_factory :rel_path do |name: 'RelPath', **options|
|
95
|
+
intersection \
|
96
|
+
path,
|
97
|
+
~abs_path,
|
98
|
+
name: name,
|
99
|
+
**options
|
100
|
+
end
|
101
|
+
|
102
|
+
|
88
103
|
# A {NRSER::Types.path} that is a directory.
|
89
104
|
#
|
90
105
|
# @param [Hash] **options
|
data/lib/nrser/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nrser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nrser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hamster
|
@@ -256,6 +256,7 @@ files:
|
|
256
256
|
- lib/nrser/errors/abstract_method_error.rb
|
257
257
|
- lib/nrser/errors/argument_error.rb
|
258
258
|
- lib/nrser/errors/attr_error.rb
|
259
|
+
- lib/nrser/errors/conflict_error.rb
|
259
260
|
- lib/nrser/errors/count_error.rb
|
260
261
|
- lib/nrser/errors/nicer_error.rb
|
261
262
|
- lib/nrser/errors/type_error.rb
|