nrser 0.1.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 736ee433c6078e250b89ebbc65455ff157888b6e
4
- data.tar.gz: a99e836e91a873ea4b06767376a6c38e30c2fe5a
3
+ metadata.gz: 1518d7452a93418bee72c151693e9f6499a41d6a
4
+ data.tar.gz: 5139a61976788fb0bb8c397a40eec24d20c695d7
5
5
  SHA512:
6
- metadata.gz: ffed557cf2652d5d9b9af71c4eb65cda37a0a165cacb7f419d9e6717cbb810ab224e3a6710e6e762c72948707e7424180faafd6acd2ab3a310aa2a326422d794
7
- data.tar.gz: 3b5307fc1dca415cb54a56ed32799b472c625c8a8d33d2dcef98e74e6ae85e21916cf2df5a211de3c4251c5e5828e5cb842942cf490cd10da8c5ad535ad8693b
6
+ metadata.gz: eb32f1311827dc0190db71434a798953282e3d258b3059aea03b86f6e56b57f871b7c5e8dcfe4b99844db1ec65b8782bf0c7ef3a099f1423ceeddcdf8b5ea16b
7
+ data.tar.gz: 67aad6c06d72fb6123dc74294e113bd9f2862a9eca317e64277aae9fb68169e9c48dc5e9248788ca475e1d30f2314b7cdd6958ee12792880be4ccc859c5fa6b8
@@ -56,15 +56,26 @@ module NRSER
56
56
 
57
57
  end
58
58
 
59
+ # 1. Load up extension mixins first - they don't invoke anything, just define
60
+ # methods
59
61
  require_relative './nrser/ext'
60
- require_relative './nrser/errors'
62
+
63
+ # 2. Then load up the refinements, which either include the extension mixins
64
+ # or directly define proxies and methods (but don't execute them).
65
+ #
66
+ # This way everything else should be able to use them.
67
+ #
68
+ require_relative './nrser/refinements'
69
+
70
+ # 3. Then everything else...
61
71
  require_relative './nrser/version'
72
+ require_relative './nrser/char'
73
+ require_relative './nrser/errors'
62
74
  require_relative './nrser/no_arg'
63
75
  require_relative './nrser/message'
64
76
  require_relative './nrser/env'
65
77
  require_relative './nrser/collection'
66
78
  require_relative './nrser/functions'
67
79
  require_relative './nrser/types'
68
- require_relative './nrser/refinements'
69
80
  require_relative './nrser/meta'
70
81
  require_relative './nrser/mean_streak'
@@ -0,0 +1,155 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ # Refinements
6
+ # =======================================================================
7
+
8
+ using NRSER
9
+
10
+
11
+ # Declarations
12
+ # ============================================================================
13
+
14
+ module NRSER::Char; end
15
+
16
+
17
+ # Namespace Requires
18
+ # ============================================================================
19
+
20
+ require_relative './char/special'
21
+
22
+
23
+ # Definitions
24
+ # =======================================================================
25
+
26
+ # A place to put things that work with characters.
27
+ #
28
+ # **_This is ALL based around UTF-8 by default_**
29
+ #
30
+ module NRSER::Char
31
+
32
+ # Constants
33
+ # ============================================================================
34
+
35
+ # {Regexp} that matches a control character.
36
+ #
37
+ # @return [Regexp]
38
+ #
39
+ CONTROL_RE = /[[:cntrl:]]/
40
+
41
+
42
+ # {Regexp} that matches when *all* characters are control characters.
43
+ #
44
+ # NOTE This will match the empty string.
45
+ #
46
+ # @return [Regexp]
47
+ #
48
+ ALL_CONTROL_RE = /\A[[:cntrl:]]*\z/
49
+
50
+
51
+ HEX_RE = /\A[0-9a-f]+\z/i
52
+
53
+
54
+ # Special Characters
55
+ # ----------------------------------------------------------------------------
56
+
57
+ # Special character info for the NULL character (zero byte in string).
58
+ #
59
+ # @return [NRSER::Char::Special]
60
+ #
61
+ NULL = Special.new \
62
+ char: "\u0000",
63
+ names: ['NULL', 'NUL', '<control-0000>'],
64
+ caret: '^@',
65
+ symbol: '␀'
66
+
67
+
68
+ # Module Methods
69
+ # ============================================================================
70
+
71
+ # Tests
72
+ # ----------------------------------------------------------------------------
73
+
74
+ # Test if string is a control character (returns `false` if length > 1).
75
+ #
76
+ # @param [String] char
77
+ # String to test.
78
+ #
79
+ # @return [Boolean]
80
+ # `true` if `char` is a control character.
81
+ #
82
+ def self.control? char
83
+ char.length == 1 && CONTROL_RE.match( char )
84
+ end # .control?
85
+
86
+
87
+ # Conversions
88
+ # ----------------------------------------------------------------------------
89
+
90
+ # Convert integer to UTF-8 character (length 1 string).
91
+ #
92
+ # @param [Integer] int
93
+ # Integer (decimal/base-10) representation of the character.
94
+ #
95
+ # @return [String]
96
+ # UTF-8 character.
97
+ #
98
+ # @raise
99
+ # When conversion can't be performed.
100
+ #
101
+ def self.from_i int
102
+ int.chr Encoding::UTF_8
103
+ end # .from_i
104
+
105
+ singleton_class.send :alias_method, :from_ord, :from_i
106
+ singleton_class.send :alias_method, :from_dec, :from_i
107
+
108
+
109
+ # Convert hex string to UTF-8 character (length 1 string).
110
+ #
111
+ # @param [String] hex
112
+ # Hexadecimal (base-16) number represented as a string.
113
+ #
114
+ # @return [String]
115
+ # UTF-8 character.
116
+ #
117
+ # @raise
118
+ # When conversion can't be performed.
119
+ #
120
+ def self.from_hex hex
121
+ from_i hex.to_i( 16 )
122
+ end # .from_hex
123
+
124
+
125
+ # Convert hex string to UTF-8 character (length 1 string).
126
+ #
127
+ # @param [String | Integer] source
128
+ # Hexadecimal (base-16) number represented as a string or a non-negative
129
+ # integer.
130
+ #
131
+ # @return [String]
132
+ # UTF-8 character.
133
+ #
134
+ # @raise (see .from_hex)
135
+ #
136
+ def self.from source
137
+ case source
138
+ when HEX_RE
139
+ from_hex source
140
+ when Integer
141
+ from_i source
142
+ else
143
+ raise ArgumentError.new binding.erb <<-END
144
+ Expected hex String like '12AB' or Integer, got <%= source.class %>
145
+
146
+ Found:
147
+
148
+ <%= source.pretty_inspect %>
149
+
150
+ END
151
+ end
152
+ end # .from_hex
153
+
154
+
155
+ end # module NRSER::Char
@@ -0,0 +1,196 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ # Definitions
6
+ # =======================================================================
7
+
8
+ # Lil' structure with useful info and methods for special characters.
9
+ #
10
+ class NRSER::Char::Special
11
+
12
+ # Attributes
13
+ # ======================================================================
14
+
15
+ # The character as a length-one string (UTF-8 encoding).
16
+ #
17
+ # @return [String]
18
+ #
19
+ attr_reader :char
20
+
21
+
22
+ # Zero or more strings names for the character.
23
+ #
24
+ # @return [Array<String>]
25
+ #
26
+ attr_reader :names
27
+
28
+
29
+ # If the character is a control character, the "caret" (`^X`) style
30
+ # replacement for it.
31
+ #
32
+ # @example
33
+ # NRSER::Char::NULL.caret
34
+ # # => '^@'
35
+ #
36
+ # @return [nil]
37
+ # If we don't have a caret replacement for it.
38
+ #
39
+ # @return [String]
40
+ # If we have a caret replacement for it.
41
+ #
42
+ attr_reader :caret
43
+
44
+
45
+ # A printable Unicode "control picture" character that can be used as a
46
+ # replacement character for control characters.
47
+ #
48
+ # @see http://www.unicode.org/charts/PDF/U2400.pdf
49
+ #
50
+ # The nice things about these is they:
51
+ #
52
+ # 1. *Should* allow for replacement without changing the Ruby string
53
+ # length\*.
54
+ #
55
+ # > \* I say *should* because lengths of unicode strings can get funky
56
+ # > across different platforms due to bytes and code points and glyphs
57
+ # > and a bunch of other stuff it seems like only about three people
58
+ # > fully understand.. it often *will* change the *byte length*, and
59
+ # > who knows how that will go if you start handing it back and forth
60
+ # > to C or something else.
61
+ #
62
+ # 2. Visually represent the replaced character. You know what it was
63
+ # without having to remember caret or hex representations.
64
+ #
65
+ # 3. Have a far lower chance of ambiguity versus {#carat}, {#esc_seq}, etc.
66
+ # (is a control character or did the string really have a `^X` in it?).
67
+ #
68
+ # Drawbacks:
69
+ #
70
+ # 1. They're all gonna be outside the ASCII range, so if you are for some
71
+ # reason stuck with something that can't Unicode you're gonna get some
72
+ # gibberish at best, if not outright breakage.
73
+ #
74
+ # 2. They require font support, or you're going to probably get one of those
75
+ # little box things that we used to see all over the web before browsers
76
+ # and operating systems managed to get their shit together.
77
+ #
78
+ # @return [nil]
79
+ # If we don't have an printable symbol for this character.
80
+ #
81
+ # @return [String]
82
+ # Length 1 printable unicode string.
83
+ #
84
+ attr_reader :symbol
85
+ alias_method :picture, :symbol
86
+
87
+
88
+ # Constructor
89
+ # ======================================================================
90
+
91
+ # Instantiate a new `Special`.
92
+ #
93
+ # @param [String] char:
94
+ # The actual character as a length 1 UTF-8 string.
95
+ #
96
+ # @param [nil | String] caret:
97
+ # Optional `^X` replacement for control characters, see {#caret} for
98
+ # details.
99
+ #
100
+ # @param [Array<#to_s>] names:
101
+ # Optional names this character goes by.
102
+ #
103
+ # @param [nil | String] symbol:
104
+ # Optional printable unicode character replacement, see {#symbol} for
105
+ # details.
106
+ #
107
+ def initialize char:, names: [], caret: nil, symbol: nil
108
+ unless char.is_a?( String ) && char.length == 1
109
+ raise ArgumentError,
110
+ "char must be string of length 1"
111
+ end
112
+
113
+ @char = char.freeze
114
+ @names = names.map { |n| n.to_s.freeze }.freeze
115
+ @caret = caret.freeze
116
+ @symbol = symbol.freeze
117
+ end # #initialize
118
+
119
+
120
+ # Instance Methods
121
+ # ======================================================================
122
+
123
+ # The first of {#names} (if any).
124
+ #
125
+ # @return [nil]
126
+ # When {#names} is empty.
127
+ #
128
+ # @return [String]
129
+ # When {#names} is not empty.
130
+ #
131
+ def name
132
+ names[0]
133
+ end
134
+
135
+
136
+ # Decimal encoding of the character (with respect to UTF-8).
137
+ #
138
+ # Equivalent to `.char.ord`.
139
+ #
140
+ # @return [Fixnum]
141
+ #
142
+ def dec
143
+ char.ord
144
+ end
145
+
146
+ alias_method :ord, :dec
147
+
148
+
149
+ # @return [String]
150
+ # Hex string as it would appear in `\uXXXX`.
151
+ def hex
152
+ @hex ||= ("%04X" % char.ord).freeze
153
+ end
154
+
155
+
156
+ # @return [Boolean]
157
+ # `true` if the character is a control character.
158
+ def control?
159
+ @control ||= NRSER::Char.control?( char )
160
+ end
161
+
162
+
163
+ def esc_seq
164
+ @esc_seq ||= char.inspect[1..-2].freeze
165
+ end
166
+
167
+
168
+ # @return [Boolean]
169
+ # `true` if the character code-point is in the ASCII range.
170
+ def ascii?
171
+ char.ascii_only?
172
+ end
173
+
174
+
175
+ # Replace all occurrences of {#char} in the string.
176
+ #
177
+ # @param [String] string
178
+ # String to replace this character in.
179
+ #
180
+ # @param [Symbol | #to_s] with:
181
+ # What to replace the character with:
182
+ #
183
+ # 1. {Symbol} - this method will be called on the instance and the
184
+ # `#to_s` of the response will be used.
185
+ #
186
+ # 2. `#to_s` - string value will be used.
187
+ #
188
+ # @return [String]
189
+ # String with {#char} replaced.
190
+ #
191
+ def replace string, with: :symbol
192
+ with = public_send( with ) if with.is_a?( Symbol )
193
+ string.gsub char, with.to_s
194
+ end
195
+
196
+ end # class NRSER::Char::Special
@@ -16,3 +16,4 @@ require_relative './functions/open_struct'
16
16
  require_relative './functions/merge_by'
17
17
  require_relative './functions/tree'
18
18
  require_relative './functions/path'
19
+ require_relative './functions/git'
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requirements
4
+ # =======================================================================
5
+
6
+ # Stdlib
7
+ # -----------------------------------------------------------------------
8
+ require 'pathname'
9
+ require 'open3'
10
+
11
+
12
+ # Definitions
13
+ # =======================================================================
14
+
15
+ module NRSER
16
+ def self.git_root from
17
+ path = Pathname.new( from ).expand_path
18
+ path = path.dirname unless path.directory?
19
+
20
+ out, err, status = Open3.capture3 \
21
+ 'git rev-parse --show-toplevel',
22
+ chdir: path.to_s
23
+
24
+ if status != 0
25
+ message = \
26
+ "#{ path.to_s.inspect } does not appear to be in a Git repo\n\n" +
27
+ NRSER::Char::NULL.replace( err ) + "\n"
28
+
29
+ raise SystemCallError.new message, status.exitstatus
30
+ end
31
+
32
+ out.chomp
33
+ end
34
+ end
@@ -1,17 +1,3 @@
1
- # Requirements
2
- # =======================================================================
3
-
4
- # Stdlib
5
- # -----------------------------------------------------------------------
6
-
7
- # Deps
8
- # -----------------------------------------------------------------------
9
-
10
- # Project / Package
11
- # -----------------------------------------------------------------------
12
- require 'nrser/functions/object'
13
-
14
-
15
1
  # Definitions
16
2
  # =======================================================================
17
3
 
@@ -1,8 +1,3 @@
1
- require 'pathname'
2
-
3
- require_relative '../functions/string'
4
- require_relative '../functions/text'
5
-
6
1
  module NRSER
7
2
  refine String do
8
3
  def squish
@@ -1,5 +1,5 @@
1
1
  module NRSER
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
 
4
4
  module Version
5
5
 
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.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - nrser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-29 00:00:00.000000000 Z
11
+ date: 2018-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster
@@ -214,6 +214,8 @@ files:
214
214
  - LICENSE.txt
215
215
  - README.md
216
216
  - lib/nrser.rb
217
+ - lib/nrser/char.rb
218
+ - lib/nrser/char/special.rb
217
219
  - lib/nrser/collection.rb
218
220
  - lib/nrser/env.rb
219
221
  - lib/nrser/env/path.rb
@@ -233,6 +235,7 @@ files:
233
235
  - lib/nrser/functions/enumerable/find_all_map.rb
234
236
  - lib/nrser/functions/enumerable/find_map.rb
235
237
  - lib/nrser/functions/exception.rb
238
+ - lib/nrser/functions/git.rb
236
239
  - lib/nrser/functions/hash.rb
237
240
  - lib/nrser/functions/hash/bury.rb
238
241
  - lib/nrser/functions/hash/deep_merge.rb