'use strict';

var types_generic_anyOf = require('./any-of.cjs');
require('../../utils/types/array.cjs');
require('../../utils/inheritance.cjs');
require('../../utils/types/object.cjs');
require('../../utils/types/iterable.cjs');
require('../../utils/types/set.cjs');
require('crypto');
require('bs58');
require('multiformats/bases/base58');
require('varint');
require('../../utils/encoding/ss-58.cjs');
require('blake2b');
require('../../utils/types/bytes.cjs');
require('../../utils/interfaces.cjs');
require('../../utils/assert.cjs');
require('../../utils/error.cjs');
require('../../utils/types/string.cjs');
require('./with-from.cjs');

/**
 * Enhances `prototype.eq` of the provided class to make it catch `null`ish values and
 * attempt to instantiate a new value of the supplied class in case if constructor is different.
 * @template C
 * @param {C} klass
 * @returns {C}
 */
function withEq(klass) {
  const name = `withEq(${klass.name})`;

  const obj = {
    [name]: class extends klass {
      eq(other) {
        if (other == null) {
          return false;
        } else if (Object.is(this, other)) {
          return true;
        } else {
          let compareWith = other;
          const { value, constructor } = this;
          const tryFrom = [
            constructor,
            value?.constructor,
            value?.constructor?.Class,
          ].filter((fn) => typeof fn?.from === 'function');
          try {
            compareWith = constructor.from(types_generic_anyOf(...tryFrom).from(compareWith));
          } catch (err) {
            return false;
          }

          return super.eq(compareWith);
        }
      }
    },
  };

  return obj[name];
}

module.exports = withEq;
//# sourceMappingURL=with-eq.cjs.map
