'use strict';

require('../../utils/types/array.cjs');
var utils_types_iterable = require('../../utils/types/iterable.cjs');
require('crypto');
require('bs58');
require('multiformats/bases/base58');
require('varint');
require('../../utils/encoding/ss-58.cjs');
var types_generic_withFrom = require('./with-from.cjs');
require('../../utils/inheritance.cjs');
require('../../utils/types/object.cjs');
require('../../utils/types/set.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');

class NeverInstantiated {
  constructor() {
    throw new Error('Should never be instantiated');
  }
}

/**
 * Creates a new type that can be constructed from any of the provided types.
 * The resulting type will attempt to parse a value using each provided type in order,
 * returning the first successful construction or throwing an error if none succeed.
 *
 * @template T
 * @param {...T[]} classes - Array of types to try constructing from
 * @returns {anyOfTypes<T>} A new type that can be constructed from any of the provided types
 */
function anyOf(...classes) {
  const name = `anyOf(${utils_types_iterable.fmtIterable(classes.map((klass) => klass.name))})`;

  const obj = {
    [name]: class extends types_generic_withFrom(NeverInstantiated, (value) => {
      let err;

      for (const klass of classes) {
        try {
          return klass.from(value);
        } catch (e) {
          if (err != null) {
            e.message = `${err.message}; ${e.message}`;
          }

          err = e;
        }
      }

      throw err;
    }) {},
  };

  return obj[name];
}

module.exports = anyOf;
//# sourceMappingURL=any-of.cjs.map
