Class: IcAgent::Candid::RecordClass

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

Overview

Represents an IDL Record

Direct Known Subclasses

TupleClass

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) ⇒ RecordClass

Returns a new instance of RecordClass.



775
776
777
778
# File 'lib/ic_agent/candid.rb', line 775

def initialize(field)
  super()
  @fields = field.sort_by { |k, _v| IcAgent::Utils.label_hash(k) }.to_h
end

Instance Method Details

#_build_type_table_impl(type_table) ⇒ Object



808
809
810
811
812
813
814
815
816
817
818
819
820
# File 'lib/ic_agent/candid.rb', line 808

def _build_type_table_impl(type_table)
  @fields.values.each do |field_value|
    field_value.send(:build_type_table, type_table)
  end

  op_code = LEB128.encode_signed(TypeIds::Record).string
  length = LEB128.encode_signed(@fields.size).string

  fields = @fields.map { |k, v|
    LEB128.encode_signed(IcAgent::Utils.label_hash(k)).string + v.encode_type(type_table)
  }.join.b
  type_table.add(self, op_code + length + fields)
end

#covariant(x) ⇒ Object

Raises:

  • (ArgumentError)


792
793
794
795
796
797
798
799
800
801
# File 'lib/ic_agent/candid.rb', line 792

def covariant(x)
  raise ArgumentError, 'Expected dict type input.' unless x.is_a?(Hash)

  @fields.each do |k, v|
    raise ArgumentError, "Record is missing key #{k}" unless x.key?(k)
    return false unless v.covariant(x[k])
  end

  true
end

#decode_value(b, t) ⇒ Object

Raises:

  • (ArgumentError)


822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
# File 'lib/ic_agent/candid.rb', line 822

def decode_value(b, t)
  record = check_type(t)
  raise ArgumentError, 'Not a record type' unless record.is_a?(RecordClass)

  x = {}
  idx = 0
  keys = @fields.keys
  @fields.each do |k, v|
    if idx >= @fields.length || IcAgent::Utils.label_hash(keys[idx]) != IcAgent::Utils.label_hash(k)
      # skip field
      v.decode_value(b, v)
      next
    end

    expect_key = keys[idx]
    expected_value = @fields[expect_key]
    x[expect_key] = expected_value.decode_value(b, v)
    idx += 1
  end

  raise ArgumentError, "Cannot find field #{keys[idx]}" if idx < @fields.length

  x
end

#displayObject



856
857
858
859
860
# File 'lib/ic_agent/candid.rb', line 856

def display
  d = {}
  @fields.each { |k, v| d[v] = v.display }
  "record #{d}"
end

#encode_value(val) ⇒ Object



803
804
805
806
# File 'lib/ic_agent/candid.rb', line 803

def encode_value(val)
  bufs = @fields.map { |k, v| v.encode_value(val[k]) }
  bufs.join.b
end

#idObject



852
853
854
# File 'lib/ic_agent/candid.rb', line 852

def id
  TypeIds::Record
end

#nameObject



847
848
849
850
# File 'lib/ic_agent/candid.rb', line 847

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

#try_as_tupleObject



780
781
782
783
784
785
786
787
788
789
790
# File 'lib/ic_agent/candid.rb', line 780

def try_as_tuple
  res = []
  idx = 0
  @fields.each do |k, v|
    return nil unless k == "_#{idx}_" # check

    res << v
    idx += 1
  end
  res
end