// Generated by nautilus-codegen. Do not edit manually.

function _normalizeHstoreValue(value) {
  return value == null ? null : String(value);
}

function _isHstoreEntriesBuilder(value) {
  return (
    value != null
    && typeof value === 'object'
    && !Array.isArray(value)
    && Object.prototype.hasOwnProperty.call(value, 'entries')
  );
}

function _isHstoreEntries(value) {
  return value != null && typeof value !== 'string' && typeof value[Symbol.iterator] === 'function';
}

function _toHstoreRecord(value = {}) {
  if (value == null) return {};
  if (value instanceof Hstore) return value.asMap();
  if (_isHstoreEntriesBuilder(value)) return _toHstoreRecord(value.entries);
  if (Array.isArray(value) || value instanceof Map || _isHstoreEntries(value)) {
    return Object.fromEntries(
      Array.from(value, ([key, item]) => [String(key), _normalizeHstoreValue(item)]),
    );
  }
  return Object.fromEntries(
    Object.entries(value).map(([key, item]) => [key, _normalizeHstoreValue(item)]),
  );
}

export class Hstore {
  constructor(value = {}) {
    this.value = _toHstoreRecord(value);
  }

  static empty() {
    return new Hstore();
  }

  static from(value) {
    return value instanceof Hstore ? value : new Hstore(value);
  }

  static fromEntries(entries) {
    return new Hstore(entries);
  }

  static toWireInput(value) {
    return _toHstoreRecord(value);
  }

  asMap() {
    return { ...this.value };
  }

  toWire() {
    return this.asMap();
  }

  get(key) {
    return this.value[key];
  }

  has(key) {
    return Object.prototype.hasOwnProperty.call(this.value, key);
  }

  with(key, value) {
    return new Hstore({ ...this.value, [key]: _normalizeHstoreValue(value) });
  }

  withNull(key) {
    return this.with(key, null);
  }

  entries() {
    return Object.entries(this.value);
  }

  keys() {
    return Object.keys(this.value);
  }

  get size() {
    return this.keys().length;
  }

  equals(other) {
    const otherValue = other instanceof Hstore ? other.value : _toHstoreRecord(other);
    const left = Object.keys(this.value);
    const right = Object.keys(otherValue ?? {});
    return left.length === right.length && left.every(key => this.value[key] === otherValue[key]);
  }

  [Symbol.iterator]() {
    return this.entries()[Symbol.iterator]();
  }
}
