// Auto generated by Craby. DO NOT EDIT.
#pragma once

#include "cxx.h"
#include "ffi.rs.h"
#include <react/bridging/Bridging.h>
#include <variant>
#include <iterator>
#include <algorithm>

using namespace facebook;

namespace reactnativenitrotor {

class RustVecBuffer : public jsi::MutableBuffer {
public:
  explicit RustVecBuffer(rust::Vec<uint8_t> vec)
    : vec_(std::move(vec)) {}

  ~RustVecBuffer() override = default;

  size_t size() const override {
    return vec_.size();
  }

  uint8_t* data() override {
    return const_cast<uint8_t*>(vec_.data());
  }

private:
  rust::Vec<uint8_t> vec_;
};

} // namespace reactnativenitrotor

namespace facebook {
namespace react {

template <>
struct Bridging<std::monostate> {
  static std::monostate fromJs(jsi::Runtime& rt, const jsi::Value &value, std::shared_ptr<CallInvoker> callInvoker) {
    return std::monostate{};
  }

  static jsi::Value toJs(jsi::Runtime& rt, const std::monostate& value) {
    return jsi::Value::undefined();
  }
};

template <>
struct Bridging<rust::Str> {
  static rust::Str fromJs(jsi::Runtime& rt, const jsi::Value &value, std::shared_ptr<CallInvoker> callInvoker) {
    auto str = value.asString(rt).utf8(rt);
    return rust::Str(str.data(), str.size());
  }

  static jsi::Value toJs(jsi::Runtime& rt, const rust::Str& value) {
    return react::bridging::toJs(rt, std::string(value.data(), value.size()));
  }
};

template <>
struct Bridging<rust::String> {
  static rust::String fromJs(jsi::Runtime& rt, const jsi::Value &value, std::shared_ptr<CallInvoker> callInvoker) {
    auto str = value.asString(rt).utf8(rt);
    return rust::String(str.data(), str.size());
  }

  static jsi::Value toJs(jsi::Runtime& rt, const rust::String& value) {
    return react::bridging::toJs(rt, std::string(value.data(), value.size()));
  }
};

template <>
struct Bridging<rust::Vec<uint8_t>> {
  static rust::Vec<uint8_t> fromJs(jsi::Runtime& rt, const jsi::Value &value, std::shared_ptr<CallInvoker> callInvoker) {
    auto arrayBuffer = value.asObject(rt).getArrayBuffer(rt);
    uint8_t* data = arrayBuffer.data(rt);
    size_t size = arrayBuffer.size(rt);
    rust::Vec<uint8_t> vec;
    vec.reserve(size);

    std::copy(data, data + size, std::back_inserter(vec));

    return vec;
  }

  static jsi::Value toJs(jsi::Runtime& rt, const rust::Vec<uint8_t>& vec) {
    auto buffer = std::make_shared<reactnativenitrotor::RustVecBuffer>(std::move(vec));
    return jsi::ArrayBuffer(rt, buffer);
  }
};

template <typename T>
struct Bridging<rust::Vec<T>> {
  static rust::Vec<T> fromJs(jsi::Runtime& rt, const jsi::Value &value, std::shared_ptr<CallInvoker> callInvoker) {
    auto arr = value.asObject(rt).asArray(rt);
    size_t len = arr.length(rt);
    rust::Vec<T> vec;
    vec.reserve(len);

    for (size_t i = 0; i < len; i++) {
      auto element = arr.getValueAtIndex(rt, i);
      vec.push_back(react::bridging::fromJs<T>(rt, element, callInvoker));
    }

    return vec;
  }

  static jsi::Array toJs(jsi::Runtime& rt, const rust::Vec<T>& vec) {
    auto arr = jsi::Array(rt, vec.size());

    for (size_t i = 0; i < vec.size(); i++) {
      auto jsElement = react::bridging::toJs(rt, vec[i]);
      arr.setValueAtIndex(rt, i, jsElement);
    }

    return arr;
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HiddenServiceParams> {
  static craby::reactnativenitrotor::bridging::HiddenServiceParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$port = obj.getProperty(rt, "port");
    auto obj$targetPort = obj.getProperty(rt, "target_port");

    auto _obj$port = react::bridging::fromJs<double>(rt, obj$port, callInvoker);
    auto _obj$targetPort = react::bridging::fromJs<double>(rt, obj$targetPort, callInvoker);

    craby::reactnativenitrotor::bridging::HiddenServiceParams ret = {
      _obj$port,
      _obj$targetPort
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HiddenServiceParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$port = react::bridging::toJs(rt, value.port);
    auto _obj$targetPort = react::bridging::toJs(rt, value.target_port);

    obj.setProperty(rt, "port", _obj$port);
    obj.setProperty(rt, "target_port", _obj$targetPort);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HiddenServiceResponse> {
  static craby::reactnativenitrotor::bridging::HiddenServiceResponse fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$isSuccess = obj.getProperty(rt, "is_success");
    auto obj$onionAddress = obj.getProperty(rt, "onion_address");
    auto obj$control = obj.getProperty(rt, "control");

    auto _obj$isSuccess = react::bridging::fromJs<bool>(rt, obj$isSuccess, callInvoker);
    auto _obj$onionAddress = react::bridging::fromJs<rust::String>(rt, obj$onionAddress, callInvoker);
    auto _obj$control = react::bridging::fromJs<rust::String>(rt, obj$control, callInvoker);

    craby::reactnativenitrotor::bridging::HiddenServiceResponse ret = {
      _obj$isSuccess,
      _obj$onionAddress,
      _obj$control
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HiddenServiceResponse value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$isSuccess = react::bridging::toJs(rt, value.is_success);
    auto _obj$onionAddress = react::bridging::toJs(rt, value.onion_address);
    auto _obj$control = react::bridging::toJs(rt, value.control);

    obj.setProperty(rt, "is_success", _obj$isSuccess);
    obj.setProperty(rt, "onion_address", _obj$onionAddress);
    obj.setProperty(rt, "control", _obj$control);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HttpDeleteParams> {
  static craby::reactnativenitrotor::bridging::HttpDeleteParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$url = obj.getProperty(rt, "url");
    auto obj$headers = obj.getProperty(rt, "headers");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");
    auto obj$trustInvalidCerts = obj.getProperty(rt, "trust_invalid_certs");

    auto _obj$url = react::bridging::fromJs<rust::String>(rt, obj$url, callInvoker);
    auto _obj$headers = react::bridging::fromJs<rust::String>(rt, obj$headers, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);
    auto _obj$trustInvalidCerts = react::bridging::fromJs<bool>(rt, obj$trustInvalidCerts, callInvoker);

    craby::reactnativenitrotor::bridging::HttpDeleteParams ret = {
      _obj$url,
      _obj$headers,
      _obj$timeoutMs,
      _obj$trustInvalidCerts
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HttpDeleteParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$url = react::bridging::toJs(rt, value.url);
    auto _obj$headers = react::bridging::toJs(rt, value.headers);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);
    auto _obj$trustInvalidCerts = react::bridging::toJs(rt, value.trust_invalid_certs);

    obj.setProperty(rt, "url", _obj$url);
    obj.setProperty(rt, "headers", _obj$headers);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);
    obj.setProperty(rt, "trust_invalid_certs", _obj$trustInvalidCerts);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HttpGetParams> {
  static craby::reactnativenitrotor::bridging::HttpGetParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$url = obj.getProperty(rt, "url");
    auto obj$headers = obj.getProperty(rt, "headers");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");
    auto obj$trustInvalidCerts = obj.getProperty(rt, "trust_invalid_certs");

    auto _obj$url = react::bridging::fromJs<rust::String>(rt, obj$url, callInvoker);
    auto _obj$headers = react::bridging::fromJs<rust::String>(rt, obj$headers, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);
    auto _obj$trustInvalidCerts = react::bridging::fromJs<bool>(rt, obj$trustInvalidCerts, callInvoker);

    craby::reactnativenitrotor::bridging::HttpGetParams ret = {
      _obj$url,
      _obj$headers,
      _obj$timeoutMs,
      _obj$trustInvalidCerts
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HttpGetParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$url = react::bridging::toJs(rt, value.url);
    auto _obj$headers = react::bridging::toJs(rt, value.headers);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);
    auto _obj$trustInvalidCerts = react::bridging::toJs(rt, value.trust_invalid_certs);

    obj.setProperty(rt, "url", _obj$url);
    obj.setProperty(rt, "headers", _obj$headers);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);
    obj.setProperty(rt, "trust_invalid_certs", _obj$trustInvalidCerts);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HttpPostParams> {
  static craby::reactnativenitrotor::bridging::HttpPostParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$url = obj.getProperty(rt, "url");
    auto obj$body = obj.getProperty(rt, "body");
    auto obj$headers = obj.getProperty(rt, "headers");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");
    auto obj$trustInvalidCerts = obj.getProperty(rt, "trust_invalid_certs");

    auto _obj$url = react::bridging::fromJs<rust::String>(rt, obj$url, callInvoker);
    auto _obj$body = react::bridging::fromJs<rust::String>(rt, obj$body, callInvoker);
    auto _obj$headers = react::bridging::fromJs<rust::String>(rt, obj$headers, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);
    auto _obj$trustInvalidCerts = react::bridging::fromJs<bool>(rt, obj$trustInvalidCerts, callInvoker);

    craby::reactnativenitrotor::bridging::HttpPostParams ret = {
      _obj$url,
      _obj$body,
      _obj$headers,
      _obj$timeoutMs,
      _obj$trustInvalidCerts
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HttpPostParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$url = react::bridging::toJs(rt, value.url);
    auto _obj$body = react::bridging::toJs(rt, value.body);
    auto _obj$headers = react::bridging::toJs(rt, value.headers);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);
    auto _obj$trustInvalidCerts = react::bridging::toJs(rt, value.trust_invalid_certs);

    obj.setProperty(rt, "url", _obj$url);
    obj.setProperty(rt, "body", _obj$body);
    obj.setProperty(rt, "headers", _obj$headers);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);
    obj.setProperty(rt, "trust_invalid_certs", _obj$trustInvalidCerts);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HttpPutParams> {
  static craby::reactnativenitrotor::bridging::HttpPutParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$url = obj.getProperty(rt, "url");
    auto obj$body = obj.getProperty(rt, "body");
    auto obj$headers = obj.getProperty(rt, "headers");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");
    auto obj$trustInvalidCerts = obj.getProperty(rt, "trust_invalid_certs");

    auto _obj$url = react::bridging::fromJs<rust::String>(rt, obj$url, callInvoker);
    auto _obj$body = react::bridging::fromJs<rust::String>(rt, obj$body, callInvoker);
    auto _obj$headers = react::bridging::fromJs<rust::String>(rt, obj$headers, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);
    auto _obj$trustInvalidCerts = react::bridging::fromJs<bool>(rt, obj$trustInvalidCerts, callInvoker);

    craby::reactnativenitrotor::bridging::HttpPutParams ret = {
      _obj$url,
      _obj$body,
      _obj$headers,
      _obj$timeoutMs,
      _obj$trustInvalidCerts
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HttpPutParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$url = react::bridging::toJs(rt, value.url);
    auto _obj$body = react::bridging::toJs(rt, value.body);
    auto _obj$headers = react::bridging::toJs(rt, value.headers);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);
    auto _obj$trustInvalidCerts = react::bridging::toJs(rt, value.trust_invalid_certs);

    obj.setProperty(rt, "url", _obj$url);
    obj.setProperty(rt, "body", _obj$body);
    obj.setProperty(rt, "headers", _obj$headers);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);
    obj.setProperty(rt, "trust_invalid_certs", _obj$trustInvalidCerts);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::HttpResponse> {
  static craby::reactnativenitrotor::bridging::HttpResponse fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$statusCode = obj.getProperty(rt, "status_code");
    auto obj$body = obj.getProperty(rt, "body");
    auto obj$error = obj.getProperty(rt, "error");

    auto _obj$statusCode = react::bridging::fromJs<double>(rt, obj$statusCode, callInvoker);
    auto _obj$body = react::bridging::fromJs<rust::String>(rt, obj$body, callInvoker);
    auto _obj$error = react::bridging::fromJs<rust::String>(rt, obj$error, callInvoker);

    craby::reactnativenitrotor::bridging::HttpResponse ret = {
      _obj$statusCode,
      _obj$body,
      _obj$error
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::HttpResponse value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$statusCode = react::bridging::toJs(rt, value.status_code);
    auto _obj$body = react::bridging::toJs(rt, value.body);
    auto _obj$error = react::bridging::toJs(rt, value.error);

    obj.setProperty(rt, "status_code", _obj$statusCode);
    obj.setProperty(rt, "body", _obj$body);
    obj.setProperty(rt, "error", _obj$error);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::StartTorParams> {
  static craby::reactnativenitrotor::bridging::StartTorParams fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$dataDir = obj.getProperty(rt, "data_dir");
    auto obj$socksPort = obj.getProperty(rt, "socks_port");
    auto obj$targetPort = obj.getProperty(rt, "target_port");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");

    auto _obj$dataDir = react::bridging::fromJs<rust::String>(rt, obj$dataDir, callInvoker);
    auto _obj$socksPort = react::bridging::fromJs<double>(rt, obj$socksPort, callInvoker);
    auto _obj$targetPort = react::bridging::fromJs<double>(rt, obj$targetPort, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);

    craby::reactnativenitrotor::bridging::StartTorParams ret = {
      _obj$dataDir,
      _obj$socksPort,
      _obj$targetPort,
      _obj$timeoutMs
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::StartTorParams value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$dataDir = react::bridging::toJs(rt, value.data_dir);
    auto _obj$socksPort = react::bridging::toJs(rt, value.socks_port);
    auto _obj$targetPort = react::bridging::toJs(rt, value.target_port);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);

    obj.setProperty(rt, "data_dir", _obj$dataDir);
    obj.setProperty(rt, "socks_port", _obj$socksPort);
    obj.setProperty(rt, "target_port", _obj$targetPort);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::StartTorResponse> {
  static craby::reactnativenitrotor::bridging::StartTorResponse fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$isSuccess = obj.getProperty(rt, "is_success");
    auto obj$onionAddress = obj.getProperty(rt, "onion_address");
    auto obj$control = obj.getProperty(rt, "control");
    auto obj$errorMessage = obj.getProperty(rt, "error_message");

    auto _obj$isSuccess = react::bridging::fromJs<bool>(rt, obj$isSuccess, callInvoker);
    auto _obj$onionAddress = react::bridging::fromJs<rust::String>(rt, obj$onionAddress, callInvoker);
    auto _obj$control = react::bridging::fromJs<rust::String>(rt, obj$control, callInvoker);
    auto _obj$errorMessage = react::bridging::fromJs<rust::String>(rt, obj$errorMessage, callInvoker);

    craby::reactnativenitrotor::bridging::StartTorResponse ret = {
      _obj$isSuccess,
      _obj$onionAddress,
      _obj$control,
      _obj$errorMessage
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::StartTorResponse value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$isSuccess = react::bridging::toJs(rt, value.is_success);
    auto _obj$onionAddress = react::bridging::toJs(rt, value.onion_address);
    auto _obj$control = react::bridging::toJs(rt, value.control);
    auto _obj$errorMessage = react::bridging::toJs(rt, value.error_message);

    obj.setProperty(rt, "is_success", _obj$isSuccess);
    obj.setProperty(rt, "onion_address", _obj$onionAddress);
    obj.setProperty(rt, "control", _obj$control);
    obj.setProperty(rt, "error_message", _obj$errorMessage);

    return jsi::Value(rt, obj);
  }
};

template <>
struct Bridging<craby::reactnativenitrotor::bridging::TorConfig> {
  static craby::reactnativenitrotor::bridging::TorConfig fromJs(jsi::Runtime &rt, const jsi::Value& value, std::shared_ptr<CallInvoker> callInvoker) {
    auto obj = value.asObject(rt);
    auto obj$socksPort = obj.getProperty(rt, "socks_port");
    auto obj$dataDir = obj.getProperty(rt, "data_dir");
    auto obj$timeoutMs = obj.getProperty(rt, "timeout_ms");

    auto _obj$socksPort = react::bridging::fromJs<double>(rt, obj$socksPort, callInvoker);
    auto _obj$dataDir = react::bridging::fromJs<rust::String>(rt, obj$dataDir, callInvoker);
    auto _obj$timeoutMs = react::bridging::fromJs<double>(rt, obj$timeoutMs, callInvoker);

    craby::reactnativenitrotor::bridging::TorConfig ret = {
      _obj$socksPort,
      _obj$dataDir,
      _obj$timeoutMs
    };

    return ret;
  }

  static jsi::Value toJs(jsi::Runtime &rt, craby::reactnativenitrotor::bridging::TorConfig value) {
    jsi::Object obj = jsi::Object(rt);
    auto _obj$socksPort = react::bridging::toJs(rt, value.socks_port);
    auto _obj$dataDir = react::bridging::toJs(rt, value.data_dir);
    auto _obj$timeoutMs = react::bridging::toJs(rt, value.timeout_ms);

    obj.setProperty(rt, "socks_port", _obj$socksPort);
    obj.setProperty(rt, "data_dir", _obj$dataDir);
    obj.setProperty(rt, "timeout_ms", _obj$timeoutMs);

    return jsi::Value(rt, obj);
  }
};

} // namespace react
} // namespace facebook
