Class: NRSER::Env::Path

Inherits:
Object
  • Object
show all
Includes:
Enumerable, NRSER::Ext::Enumerable
Defined in:
lib/nrser/env/path.rb

Constant Summary collapse

SEPARATOR =

Character used to separate path entries in string format.

Returns:

  • (String)
':'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from NRSER::Ext::Enumerable

#count_by, #enumerate_as_values, #find_bounded, #find_map, #find_only, #map_values, #only, #only!, #to_h_by, #try_find

Constructor Details

#initialize(source, env_key: nil) ⇒ Path

Instantiate a new ‘NRSER::Env::Path`.



172
173
174
175
176
# File 'lib/nrser/env/path.rb', line 172

def initialize source, env_key: nil
  @env_key = env_key.to_s.freeze
  @source = source.dup.freeze
  @value = self.class.normalize source
end

Instance Attribute Details

#env_keynil | String (readonly)

Key for the value in ‘ENV` that the object represents. This is set when loading from `ENV` and used to know where to write when saving back to it.

Returns:

  • (nil | String)


151
152
153
# File 'lib/nrser/env/path.rb', line 151

def env_key
  @env_key
end

#sourcenil | String | #each_index (readonly)

The object that was originally provided at construction.

Returns:

  • (nil | String | #each_index)


158
159
160
# File 'lib/nrser/env/path.rb', line 158

def source
  @source
end

#valueHamster::Vector<String> (readonly)

The actual internal list of paths.

Returns:

  • (Hamster::Vector<String>)


165
166
167
# File 'lib/nrser/env/path.rb', line 165

def value
  @value
end

Class Method Details

.from_ENV(env_key) ⇒ return_type

TODO:

Document from_env method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



138
139
140
# File 'lib/nrser/env/path.rb', line 138

def self.from_ENV env_key
  new ENV[env_key.to_s], env_key: env_key
end

.matches_pattern?(path, *patterns) ⇒ Boolean

See if a ‘path` matches any of `patterns`.

Short-circuits as soon as a match is found (so patterns may not all be tested).

Parameters:

  • path (String)

    Path to test against.

  • *patterns (Array<String | Proc<String=>Boolean> | Regexp>)

    Patterns to test:

    • ‘String` - test if it and `path` are equal (`==`)

    • ‘Proc<String=>Boolean>` - call with `path` and evaluate result as Boolean.

    • ‘Regexp` - test if it matches `path` (`=~`)

Returns:

  • (Boolean)

    ‘true` if any of `patterns` match `path`.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/nrser/env/path.rb', line 109

def self.matches_pattern? path, *patterns
  patterns.any? do |pattern|
    case pattern
    when String
      path == pattern
    when Proc
      pattern.call path
    when Regexp
      path =~ pattern
    else
      raise TypeError.new binding.erb <<-END
        Each `*patterns` arg should be String, Proc or Regexp, found:
        
            <%= pattern.pretty_inspect %>
        
      END
    end
  end
end

.normalize(source) ⇒ return_type

TODO:

Document normalize method.

Returns @todo Document return value.

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (return_type)

    @todo Document return value.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/nrser/env/path.rb', line 55

def self.normalize source
  paths = if source.nil?
    []
  
  elsif source.is_a?( String )
    source.to_s.split SEPARATOR
    
  elsif NRSER.array_like?( source )
    # Flatten it if supported
    source = source.flatten if source.respond_to?( :flatten )
    
    # Stringify each segment, split them and concat results
    source.flat_map { |entry| entry.to_s.split SEPARATOR }
  
  else
    raise ArgumentError.new binding.erb <<-END
      Expected a string or an "array-like" source, found:
      
          <%= source.pretty_inspect %>
      
    END
  end
  
  Hamster::Vector.new paths.
    # Get rid of empty paths
    reject( &:empty? ).
    # Get rid of duplicates
    uniq.
    # Freeze all the strings
    map( &:freeze )
end

Instance Method Details

#append(source) ⇒ self

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (self)


206
207
208
209
210
211
212
213
214
215
216
# File 'lib/nrser/env/path.rb', line 206

def append source
  # Normalize the new source to a flat array of strings
  paths = self.class.normalize source
  
  # The new value is the current paths with the new paths appended, with
  # any paths in the current path removed from the new ones (de-duplication)
  @value = (@value + paths).uniq
  
  # Return self for chain-ability
  self
end

#each(&block) ⇒ self, Enumerator

Support for Enumerable mixin. Yields each path in order.

Specifically, proxies to Hamster::Vector#each

Parameters:

  • &block (nil | Proc<(String)=>*>)

    When present, block will be called once for each string path in this object. First path is most prominent, down to least last.

Returns:

  • (self)

    When ‘&block` is provided.

  • (Enumerator)

    When ‘&block` is omitted.

See Also:



274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/nrser/env/path.rb', line 274

def each &block
  if block
    # Proxy for yielding
    @value.each &block
    
    # Return self for chain-ability
    self
  else
    # Return the {Enumerator} from the vector
    @value.each
  end
end

#insert(source, before: nil, after: nil) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/nrser/env/path.rb', line 222

def insert source, before: nil, after: nil
  paths = self.class.normalize source
  
  before_index = if before
    @value.find_index do |path|
      self.class.matches_pattern? path, *before
    end
  end
  
  after_index = if after
    index = @value.rindex { |path| self.class.matches_pattern? path, *after }
    index += 1 if index
  end
  
  insert_index = if after_index && before_index
    # Make sure the conditions don't conflict with each other
    if after_index > before_index
      raise "Conflicting bounds!"
    end
    
    # Insert as far "down" the path as allowed
    [before_index, after_index].max
  else
    # Use the one that is not `nil`, or insert at the end if they both are
    before_index || after_index || @value.length
  end
  
  @value = @value.insert( insert_index, *paths ).uniq
  
  self
end

#prepend(source) ⇒ self Also known as: unshift, >>, push, <<

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (self)


186
187
188
189
190
191
192
193
194
195
196
# File 'lib/nrser/env/path.rb', line 186

def prepend source
  # Normalize the new source to a flat array of strings
  paths = self.class.normalize source
  
  # The new value is the normalized paths followed by the current paths
  # with the new ones removed (de-duplication)
  @value = (paths + @value).uniq
  
  # Return self for chain-ability
  self
end

#to_aArray<String>

The string paths in a new stdlib ‘Array`. Mutating this array will have no effect on the NRSER::Env::Path data.

Returns:

  • (Array<String>)


302
303
304
# File 'lib/nrser/env/path.rb', line 302

def to_a
  @value.to_a
end

#to_sString

The paths joined with ‘:’.

Returns:

  • (String)


292
293
294
# File 'lib/nrser/env/path.rb', line 292

def to_s
  @value.join SEPARATOR
end