Class: Kerbi::State::Entry

Inherits:
Object
  • Object
show all
Defined in:
lib/state/entry.rb

Overview

Represents a single Kerbi state entry.

Constant Summary collapse

CANDIDATE_PREFIX =
"[cand]-"
ATTRS =
%i[tag message values default_values created_at]
SETTABLE_ATTRS =
%i[message created_at]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(set, dict) ⇒ Entry

Returns a new instance of Entry.



23
24
25
26
27
28
29
30
# File 'lib/state/entry.rb', line 23

def initialize(set, dict)
  @set = set
  ATTRS.each do |attr|
    instance_variable_set("@#{attr}", dict[attr].freeze)
  end
  @_was_validated = false
  @validation_errors = []
end

Instance Attribute Details

#created_atObject

Returns the value of attribute created_at.



19
20
21
# File 'lib/state/entry.rb', line 19

def created_at
  @created_at
end

#default_valuesObject

Returns the value of attribute default_values.



17
18
19
# File 'lib/state/entry.rb', line 17

def default_values
  @default_values
end

#messageObject

Returns the value of attribute message.



16
17
18
# File 'lib/state/entry.rb', line 16

def message
  @message
end

#setObject

Returns the value of attribute set.



13
14
15
# File 'lib/state/entry.rb', line 13

def set
  @set
end

#tagObject

Returns the value of attribute tag.



15
16
17
# File 'lib/state/entry.rb', line 15

def tag
  @tag
end

#validation_errorsObject (readonly)

Returns the value of attribute validation_errors.



21
22
23
# File 'lib/state/entry.rb', line 21

def validation_errors
  @validation_errors
end

#valuesObject

Returns the value of attribute values.



18
19
20
# File 'lib/state/entry.rb', line 18

def values
  @values
end

Class Method Details

.from_dict(set, dict = {}) ⇒ Kerbi::State::Entry

Parameters:

  • dict (Hash) (defaults to: {})

Returns:



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/state/entry.rb', line 155

def self.from_dict(set, dict={})
  dict.deep_symbolize_keys!
  dict.slice!(*ATTRS)

  self.new(
    set,
    **dict,
    values: dict[:values] || {},
    default_values: dict[:default_values] || {},
    created_at: (Time.parse(dict[:created_at]) rescue nil)
  )
end

.versioned?(expr) ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/state/entry.rb', line 168

def self.versioned?(expr)
  Gem::Version.correct?(expr)
end

Instance Method Details

#assign_attr(attr_name, new_value) ⇒ String

Dynamically assign as a user.

Parameters:

  • attr_name (String|Symbol)
  • new_value (Object)

Returns:

  • (String)

    the old value, for convenience



83
84
85
86
87
88
89
90
91
# File 'lib/state/entry.rb', line 83

def assign_attr(attr_name, new_value)
  if SETTABLE_ATTRS.include?(attr_name.to_sym)
    old_value = send(attr_name)
    send("#{attr_name}=", new_value)
    old_value
  else
    raise Kerbi::NoSuchStateAttrName
  end
end

#candidate?TrueClass, FalseClass

A state entry is a ‘candidate’ if its tag has the candidate signature - that is it starts with [cand]-.

Returns:

  • (TrueClass, FalseClass)


35
36
37
# File 'lib/state/entry.rb', line 35

def candidate?
  tag.start_with?(CANDIDATE_PREFIX)
end

#committed?TrueClass, FalseClass

Convenience method that returns the negation of #candidate?

Returns:

  • (TrueClass, FalseClass)


42
43
44
# File 'lib/state/entry.rb', line 42

def committed?
  !candidate?
end

#demoteString

Adds the [cand]- flag to this entry’s tag, making this entry gain candidate status.

Raises an exception if this entry was already a candidate.

Returns:

  • (String)

    the old tag, for convenience

Raises:



124
125
126
127
128
129
# File 'lib/state/entry.rb', line 124

def demote
  raise Kerbi::StateNotDemotable unless committed?
  old_tag = tag
  self.tag = "#{CANDIDATE_PREFIX}#{tag}"
  old_tag
end

#overridden_keysArray<String>

Convenience method to get all overridden keys between the values and default_values dicts.

Returns:

  • (Array<String>)


135
136
137
# File 'lib/state/entry.rb', line 135

def overridden_keys
  (delta = overrides_delta) ? delta.keys.map(&:to_s) : []
end

#overrides_deltaHash

Computes a delta between this state’s values and its default values.

Returns:

  • (Hash)


70
71
72
73
74
75
76
# File 'lib/state/entry.rb', line 70

def overrides_delta
  if values.is_a?(Hash) & default_values.is_a?(Hash)
    Kerbi::Utils::Misc.deep_hash_diff(default_values, values)
  else
    nil
  end
end

#promoteString

Removes the [cand]- part of the tag, making this entry lose its candidate status.

Raises an exception if this entry was not a candidate.

Returns:

  • (String)

    the old tag, for convenience

Raises:



111
112
113
114
115
116
# File 'lib/state/entry.rb', line 111

def promote
  raise Kerbi::StateNotPromotable unless candidate?
  old_tag = tag
  self.tag = tag[CANDIDATE_PREFIX.length..]
  old_tag
end

#retag(new_tag_expr) ⇒ String

Replace current tag with a new one, where the new one can contain special interpolatable words like

Parameters:

  • new_tag_expr (String)

Returns:

  • (String)

    the old tag, for convenience



99
100
101
102
103
# File 'lib/state/entry.rb', line 99

def retag(new_tag_expr)
  old_tag = tag
  self.tag = set.resolve_write_tag_expr(new_tag_expr)
  old_tag
end

#to_hObject Also known as: serialize



139
140
141
142
143
144
145
146
# File 'lib/state/entry.rb', line 139

def to_h
  special_ser = {
    values: values || {},
    default_values: default_values || {},
    created_at: created_at.to_s
  }
  Hash[ATTRS.map{|k|[k, send(k)]}].merge(special_ser)
end

#to_jsonObject



149
150
151
# File 'lib/state/entry.rb', line 149

def to_json
  JSON.dump(serialize)
end

#valid?Boolean

Returns:

  • (Boolean)


61
62
63
64
# File 'lib/state/entry.rb', line 61

def valid?
  raise "valid? called before #validate" unless @_was_validated
  validation_errors.empty?
end

#validateNilClass

Ghetto attribute validation. Pushes a attr => msg hash to the problems.

Returns:

  • (NilClass)


51
52
53
54
55
56
57
58
59
# File 'lib/state/entry.rb', line 51

def validate
  @validation_errors.push(
    attr: 'tag',
    msg: "Cannot be empty",
    value: tag
  ) unless tag.present?

  @_was_validated = true
end