class CryptoUnit

Constants

MAX_VALUE
NAME
UNIT_DENOMINATIONS

Says how many digits after the decimal point a denomination has.

Attributes

from_unit[R]
to_unit[R]
value[R]

Public Class Methods

new(n=nil, from_unit: 'standart', to_unit: 'standart', unit: nil) click to toggle source
# File lib/crypto_unit_base.rb, line 18
def initialize(n=nil, from_unit: 'standart', to_unit: 'standart', unit: nil)
  n = 0 if n.nil?
  if unit
    @from_unit = @to_unit = unit.downcase.to_sym
  else
    @from_unit = from_unit.downcase.to_sym
    @to_unit   = to_unit.downcase.to_sym
  end
  @value = convert_to_primary(n) if n
end

Public Instance Methods

*(i) click to toggle source

IMPORTANT: multiplication is done on primary units, not standart. 0.01*0.02 will be a larger value.

# File lib/crypto_unit_base.rb, line 98
def *(i)
  if i.kind_of?(CryptoUnit)
    self.class.new(self.to_i * i, from_unit: :primary)
  else
    self.to_i * i
  end
end
+(i) click to toggle source
# File lib/crypto_unit_base.rb, line 80
def +(i)
  if i.kind_of?(CryptoUnit)
    self.class.new(self.to_i + i, from_unit: :primary)
  else
    self.to_i + i
  end
end
-(i) click to toggle source
# File lib/crypto_unit_base.rb, line 88
def -(i)
  if i.kind_of?(CryptoUnit)
    self.class.new(self.to_i - i, from_unit: :primary)
  else
    self.to_i - i
  end
end
<(i) click to toggle source
# File lib/crypto_unit_base.rb, line 64
def <(i)
  self.to_i < i
end
<=(i) click to toggle source
# File lib/crypto_unit_base.rb, line 72
def <=(i)
  self.to_i <= i
end
==(i) click to toggle source
# File lib/crypto_unit_base.rb, line 76
def ==(i)
  self.to_i == i
end
>(i) click to toggle source
# File lib/crypto_unit_base.rb, line 60
def >(i)
  self.to_i > i
end
>=(i) click to toggle source
# File lib/crypto_unit_base.rb, line 68
def >=(i)
  self.to_i >= i
end
coerce(other) click to toggle source
# File lib/crypto_unit_base.rb, line 106
def coerce(other)
  if other.kind_of?(Integer)
    [other, self.to_i]
  else
    raise TypeError, message: "CryptoUnit cannot be coerced into anything but Integer"
  end
end
primary_value()
Alias for: to_i
primary_value=(v) click to toggle source
# File lib/crypto_unit_base.rb, line 56
def primary_value=(v)
  @value = v
end
to_i() click to toggle source
# File lib/crypto_unit_base.rb, line 41
def to_i
  return 0 if @value.nil?
  @value
end
Also aliased as: primary_value
to_milli(as: :number, format_zero: false) click to toggle source
# File lib/crypto_unit_base.rb, line 33
def to_milli(as: :number, format_zero: false)
  to_denomination(UNIT_DENOMINATIONS[:milli], as: as, format_zero: format_zero)
end
to_s() click to toggle source
# File lib/crypto_unit_base.rb, line 47
def to_s
  to_unit.to_s
end
to_standart(as: :number, format_zero: false) click to toggle source
# File lib/crypto_unit_base.rb, line 29
def to_standart(as: :number, format_zero: false)
  to_denomination(UNIT_DENOMINATIONS[:standart], as: as, format_zero: format_zero)
end
value=(n) click to toggle source
# File lib/crypto_unit_base.rb, line 51
def value=(n)
  n = 0 if n.nil?
  @value = convert_to_primary(n)
end

Protected Instance Methods

convert_to_primary(n) click to toggle source
# File lib/crypto_unit_base.rb, line 140
def convert_to_primary(n)
  n = BigDecimal(n.to_s)

  decimal_part_length = n.to_s("F").split(".")[1]
  decimal_part_length = if decimal_part_length
    decimal_part_length.sub(/0*\Z/, "").length
  else
    0
  end

  if decimal_part_length > UNIT_DENOMINATIONS[@from_unit]
    raise TooManyDigitsAfterDecimalPoint,
      "Too many digits (#{decimal_part_length}) after decimal point used for #{@from_unit} value, while #{UNIT_DENOMINATIONS[@from_unit]} allowed"
  end

  n = ("%.#{UNIT_DENOMINATIONS[@from_unit]}f" % n) # otherwise we might see a scientific notation
  n = n.split('.')
  n[1] ||= '' # in the case where there's no decimal part
  n[1] += "0"*(UNIT_DENOMINATIONS[@from_unit]-n[1].length) if n[1]

  if(n.join.to_i > self.class::MAX_VALUE)
    raise TooLarge, "Max value for #{self.class::NAME} is #{self.class::MAX_VALUE}"
  end

  n.join.to_i
end
to_denomination(digits_after_delimiter, as: :number, format_zero: false) click to toggle source
# File lib/crypto_unit_base.rb, line 116
def to_denomination(digits_after_delimiter, as: :number, format_zero: false)
  sign  = @value < 0 ? -1 : 1
  val   = @value.abs
  return val if digits_after_delimiter <= 0
  leading_zeros = "0"*(18-val.to_s.length)
  result = leading_zeros + val.to_s
  result.reverse!
  result = result.slice(0..digits_after_delimiter-1) + '.' + result.slice(digits_after_delimiter..17)
  result.reverse!
  result = result.sub(/\A0*/, '').sub(/0*\Z/, '') # remove zeros on both sides
  if as == :number
    result.to_f*sign
  else
    if result == '.'
      result = format_zero ? '0' : '0.0'
    elsif result =~ /\A\./
      result = "0#{result}"
    elsif result =~ /\.\Z/
      result = format_zero ? result[0..-2] : "#{result}0"
    end
    sign == -1 ? "-#{result}" : result
  end
end