Module: A2A::Utils::Helpers

Defined in:
lib/a2a/utils/helpers.rb

Class Method Summary collapse

Class Method Details

.blank?(string) ⇒ Boolean

Check if string is blank (nil, empty, or whitespace only)

Parameters:

  • String to check

Returns:

  • True if blank



147
148
149
# File 'lib/a2a/utils/helpers.rb', line 147

def blank?(string)
  string.nil? || string.strip.empty?
end

.camel_case(string, first_letter_uppercase: false) ⇒ String

Convert string to camelCase

Parameters:

  • String to convert

  • (defaults to: false)

    Whether first letter should be uppercase

Returns:

  • CamelCase string



108
109
110
111
112
113
114
# File 'lib/a2a/utils/helpers.rb', line 108

def camel_case(string, first_letter_uppercase: false)
  parts = string.split(/[_\-\s]+/)
  result = parts.first.downcase
  result += parts[1..].map(&:capitalize).join if parts.length > 1

  first_letter_uppercase ? result.capitalize : result
end

.deep_merge(hash1, hash2) ⇒ Hash

Deep merge two hashes

Parameters:

  • First hash

  • Second hash

Returns:

  • Merged hash



80
81
82
83
84
85
86
87
88
# File 'lib/a2a/utils/helpers.rb', line 80

def deep_merge(hash1, hash2)
  hash1.merge(hash2) do |_key, old_val, new_val|
    if old_val.is_a?(Hash) && new_val.is_a?(Hash)
      deep_merge(old_val, new_val)
    else
      new_val
    end
  end
end

.format_bytes(bytes) ⇒ String

Format bytes in human-readable format

Parameters:

  • Number of bytes

Returns:

  • Formatted string



205
206
207
208
209
210
211
212
213
# File 'lib/a2a/utils/helpers.rb', line 205

def format_bytes(bytes)
  return "0 B" if bytes.zero?

  units = %w[B KB MB GB TB PB]
  exp = (Math.log(bytes.abs) / Math.log(1024)).floor
  exp = [exp, units.length - 1].min

  "#{(bytes / (1024.0**exp)).round(2)} #{units[exp]}"
end

.generate_hex(length = 16) ⇒ String

Generate a random hex string

Parameters:

  • (defaults to: 16)

    Length of the hex string (default: 16)

Returns:

  • Random hex string



30
31
32
# File 'lib/a2a/utils/helpers.rb', line 30

def generate_hex(length = 16)
  SecureRandom.hex(length)
end

.generate_token(length = 32) ⇒ String

Generate a secure random token

Parameters:

  • (defaults to: 32)

    Length of the token (default: 32)

Returns:

  • Base64-encoded random token



39
40
41
# File 'lib/a2a/utils/helpers.rb', line 39

def generate_token(length = 32)
  Base64.urlsafe_encode64(SecureRandom.random_bytes(length), padding: false)
end

.generate_uuidString

Generate a UUID

Returns:

  • A new UUID string



21
22
23
# File 'lib/a2a/utils/helpers.rb', line 21

def generate_uuid
  SecureRandom.uuid
end

.hash_string(string, algorithm: :sha256) ⇒ String

Generate a hash of a string

Parameters:

  • String to hash

  • (defaults to: :sha256)

    Hash algorithm (:sha256, :sha1, :md5)

Returns:

  • Hex-encoded hash



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/a2a/utils/helpers.rb', line 49

def hash_string(string, algorithm: :sha256)
  case algorithm
  when :sha256
    Digest::SHA256.hexdigest(string)
  when :sha1
    Digest::SHA1.hexdigest(string)
  when :md5
    Digest::MD5.hexdigest(string)
  else
    raise ArgumentError, "Unsupported hash algorithm: #{algorithm}"
  end
end

.measure_execution_time { ... } ⇒ Hash

Measure execution time of a block

Yields:

  • Block to measure

Returns:

  • Result with :result and :duration keys



189
190
191
192
193
194
195
196
197
198
# File 'lib/a2a/utils/helpers.rb', line 189

def measure_execution_time
  start_time = Time.now
  result = yield
  end_time = Time.now

  {
    result: result,
    duration: end_time - start_time
  }
end

.present?(string) ⇒ Boolean

Check if string is present (not blank)

Parameters:

  • String to check

Returns:

  • True if present



156
157
158
# File 'lib/a2a/utils/helpers.rb', line 156

def present?(string)
  !blank?(string)
end

.retry_with_backoff(max_attempts: 3, base_delay: 1.0, max_delay: 60.0, backoff_factor: 2.0) { ... } ⇒ Object

Retry a block with exponential backoff

Parameters:

  • (defaults to: 3)

    Maximum number of attempts

  • (defaults to: 1.0)

    Base delay in seconds

  • (defaults to: 60.0)

    Maximum delay in seconds

  • (defaults to: 2.0)

    Backoff multiplier

Yields:

  • Block to retry

Returns:

  • Block result



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/a2a/utils/helpers.rb', line 169

def retry_with_backoff(max_attempts: 3, base_delay: 1.0, max_delay: 60.0, backoff_factor: 2.0)
  attempt = 1

  begin
    yield
  rescue StandardError => e
    raise e unless attempt < max_attempts

    delay = [base_delay * (backoff_factor**(attempt - 1)), max_delay].min
    sleep(delay)
    attempt += 1
    retry
  end
end

.safe_json_parse(json_string, default: nil) ⇒ Object

Safely parse JSON with error handling

Parameters:

  • JSON string to parse

  • (defaults to: nil)

    Default value if parsing fails

Returns:

  • Parsed JSON or default value



68
69
70
71
72
# File 'lib/a2a/utils/helpers.rb', line 68

def safe_json_parse(json_string, default: nil)
  JSON.parse(json_string)
rescue JSON::ParserError
  default
end

.sanitize_string(string, allowed_chars: /[a-zA-Z0-9_\-.]/) ⇒ String

Sanitize string for safe usage

Parameters:

  • String to sanitize

  • (defaults to: /[a-zA-Z0-9_\-.]/)

    Allowed characters pattern

Returns:

  • Sanitized string



138
139
140
# File 'lib/a2a/utils/helpers.rb', line 138

def sanitize_string(string, allowed_chars: /[a-zA-Z0-9_\-.]/)
  string.gsub(/[^#{allowed_chars.source}]/, "_")
end

.snake_case(string) ⇒ String

Convert string to snake_case

Parameters:

  • String to convert

Returns:

  • Snake_case string



95
96
97
98
99
100
# File 'lib/a2a/utils/helpers.rb', line 95

def snake_case(string)
  string
    .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
    .gsub(/([a-z\d])([A-Z])/, '\1_\2')
    .downcase
end

.truncate(string, length:, suffix: "...") ⇒ String

Truncate string to specified length

Parameters:

  • String to truncate

  • Maximum length

  • (defaults to: "...")

    Suffix to add if truncated

Returns:

  • Truncated string



123
124
125
126
127
128
129
130
# File 'lib/a2a/utils/helpers.rb', line 123

def truncate(string, length:, suffix: "...")
  return string if string.length <= length

  truncated_length = length - suffix.length
  return suffix if truncated_length <= 0

  string[0...truncated_length] + suffix
end

.valid_email?(email) ⇒ Boolean

Validate email format

Parameters:

  • Email to validate

Returns:

  • True if valid email format



220
221
222
223
224
225
# File 'lib/a2a/utils/helpers.rb', line 220

def valid_email?(email)
  return false if blank?(email)

  # Simple email validation regex
  email.match?(/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/)
end

.valid_url?(url) ⇒ Boolean

Validate URL format

Parameters:

  • URL to validate

Returns:

  • True if valid URL format



232
233
234
235
236
237
238
239
240
241
# File 'lib/a2a/utils/helpers.rb', line 232

def valid_url?(url)
  return false if blank?(url)

  begin
    uri = URI.parse(url)
    uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
  rescue URI::InvalidURIError
    false
  end
end