Class: IcAgent::Candid::VariantClass

Inherits:
ConstructType show all
Defined in:
lib/ic_agent/candid.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ConstructType

#check_type, #encode_type

Methods inherited from BaseType

_build_type_table_impl, #build_type_table, check_type, covariant, decode_value, encode_type, encode_value

Constructor Details

#initialize(field) ⇒ VariantClass

Returns a new instance of VariantClass.



914
915
916
917
# File 'lib/ic_agent/candid.rb', line 914

def initialize(field)
  super()
  @fields = field.sort_by { |kv| IcAgent::Utils.label_hash(kv[0]) }.to_h
end

Instance Attribute Details

#fieldsObject

Returns the value of attribute fields.



912
913
914
# File 'lib/ic_agent/candid.rb', line 912

def fields
  @fields
end

Instance Method Details

#_build_type_table_impl(type_table) ⇒ Object



945
946
947
948
949
950
951
952
953
954
955
956
# File 'lib/ic_agent/candid.rb', line 945

def _build_type_table_impl(type_table)
  @fields.each do |_, v|
    v.build_type_table(type_table)
  end
  opCode = LEB128.encode_signed(TypeIds::Variant).string
  length = LEB128.encode_signed(@fields.length).string
  fields = ''.b
  @fields.each do |k, v|
    fields += LEB128.encode_signed(IcAgent::Utils.label_hash(k)).string + v.encode_type(type_table)
  end
  type_table.add(self, opCode + length + fields)
end

#covariant(x) ⇒ Object



919
920
921
922
923
924
925
926
927
928
929
# File 'lib/ic_agent/candid.rb', line 919

def covariant(x)
  return false unless x.length == 1

  @fields.each do |k, v|
    next if !x.key?(k) || v.covariant(x[k])

    return false
  end

  true
end

#decode_value(b, t) ⇒ Object



958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
# File 'lib/ic_agent/candid.rb', line 958

def decode_value(b, t)
  variant = check_type(t)
  raise 'Not a variant type' unless variant.is_a?(VariantClass)

  idx = IcAgent::Candid.leb128u_decode(b)
  raise "Invalid variant index: #{idx}" if idx >= variant.fields.length

  keys = variant.fields.keys
  wireHash = keys[idx]
  wireType = variant.fields[wireHash]

  @fields.each do |key, expectType|
    next unless IcAgent::Utils.label_hash(wireHash) == IcAgent::Utils.label_hash(key)

    ret = {}
    value = expectType ? expectType.decode_value(b, wireType) : nil
    ret[key] = value
    return ret
  end

  raise "Cannot find field hash #{wireHash}"
end

#displayObject



990
991
992
993
994
995
996
# File 'lib/ic_agent/candid.rb', line 990

def display
  d = {}
  @fields.each do |k, v|
    d[k] = v.name || ''
  end
  "variant #{d}"
end

#encode_value(val) ⇒ Object



931
932
933
934
935
936
937
938
939
940
941
942
943
# File 'lib/ic_agent/candid.rb', line 931

def encode_value(val)
  idx = 0
  @fields.each do |name, ty|
    if val.key?(name)
      count = LEB128.encode_signed(idx).string
      buf = ty.encode_value(val[name])
      return count + buf
    end

    idx += 1
  end
  raise "Variant has no data: #{val}"
end

#idObject



986
987
988
# File 'lib/ic_agent/candid.rb', line 986

def id
  TypeIds::Variant
end

#nameObject



981
982
983
984
# File 'lib/ic_agent/candid.rb', line 981

def name
  fields = @fields.map { |k, v| "#{k}:#{v.name || ''}" }.join(';')
  "variant {#{fields}}"
end