#include "wrapper.h"
#include <sstream>
#include <chrono>
#include <thread>
#include <pvxs/log.h>
namespace pvxs_wrapper {
std::string ValueWrapper::get_field_string(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
return field.as<std::string>();
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting field '") + field_name + "': " + e.what());
}
}
double ValueWrapper::get_field_double(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
return field.as<double>();
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting field '") + field_name + "': " + e.what());
}
}
int32_t ValueWrapper::get_field_int32(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
return field.as<int32_t>();
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting field '") + field_name + "': " + e.what());
}
}
std::string ValueWrapper::to_string() const {
if (!value_.valid()) {
return "(invalid)";
}
try {
std::ostringstream ss;
ss << value_;
return ss.str();
} catch (const std::exception& e) {
return std::string("Error converting to string: ") + e.what();
}
}
std::int16_t ValueWrapper::get_field_enum(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
return field.as<std::int16_t>();
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting field '") + field_name + "': " + e.what());
}
}
rust::Vec<double> ValueWrapper::get_field_double_array(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
auto arr = field.as<pvxs::shared_array<const double>>();
rust::Vec<double> result;
for (size_t i = 0; i < arr.size(); ++i) {
result.push_back(arr[i]);
}
return result;
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting array field '") + field_name + "': " + e.what());
}
}
rust::Vec<int32_t> ValueWrapper::get_field_int32_array(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
auto arr = field.as<pvxs::shared_array<const int32_t>>();
rust::Vec<int32_t> result;
for (size_t i = 0; i < arr.size(); ++i) {
result.push_back(arr[i]);
}
return result;
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting array field '") + field_name + "': " + e.what());
}
}
rust::Vec<int16_t> ValueWrapper::get_field_enum_array(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
auto arr = field.as<pvxs::shared_array<const int16_t>>();
rust::Vec<int16_t> result;
for (size_t i = 0; i < arr.size(); ++i) {
result.push_back(arr[i]);
}
return result;
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting array field '") + field_name + "': " + e.what());
}
}
rust::Vec<rust::String> ValueWrapper::get_field_string_array(const std::string& field_name) const {
if (!value_.valid()) {
throw PvxsError("Value is not valid");
}
try {
auto field = value_[field_name];
if (!field.valid()) {
throw PvxsError("Field '" + field_name + "' not found");
}
auto arr = field.as<pvxs::shared_array<const std::string>>();
rust::Vec<rust::String> result;
for (size_t i = 0; i < arr.size(); ++i) {
result.push_back(rust::String(arr[i]));
}
return result;
} catch (const std::exception& e) {
throw PvxsError(std::string("Error getting array field '") + field_name + "': " + e.what());
}
}
std::unique_ptr<ContextWrapper> ContextWrapper::from_env() {
try {
auto config = pvxs::client::Config::fromEnv();
auto ctx = config.build();
return std::make_unique<ContextWrapper>(std::move(ctx));
} catch (const std::exception& e) {
throw PvxsError(std::string("Error creating context from environment: ") + e.what());
}
}
std::unique_ptr<ValueWrapper> ContextWrapper::get(
const std::string& pv_name,
double timeout) {
try {
auto op = context_.get(pv_name).exec();
auto result = op->wait(timeout);
return std::make_unique<ValueWrapper>(std::move(result));
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in get for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
double value,
double timeout) {
try {
context_.put(pv_name).build([value](pvxs::Value&& val) {
val["value"] = value;
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
int32_t value,
double timeout) {
try {
context_.put(pv_name).build([value](pvxs::Value&& val) {
val["value"] = value;
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
const std::string& value,
double timeout) {
try {
context_.put(pv_name).build([&value](pvxs::Value&& val) {
val["value"] = value;
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
int16_t value,
double timeout) {
try {
context_.put(pv_name).build([value](pvxs::Value&& val) {
val["value.index"] = value;
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
const rust::Vec<double>& value,
double timeout) {
try {
context_.put(pv_name).build([&value](pvxs::Value&& val) {
pvxs::shared_array<double> arr(value.size());
for (size_t i = 0; i < value.size(); ++i) {
arr[i] = value[i];
}
val["value"] = arr.freeze();
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
const rust::Vec<int32_t>& value,
double timeout) {
try {
context_.put(pv_name).build([&value](pvxs::Value&& val) {
pvxs::shared_array<int32_t> arr(value.size());
for (size_t i = 0; i < value.size(); ++i) {
arr[i] = value[i];
}
val["value"] = arr.freeze();
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
const rust::Vec<int16_t>& value,
double timeout) {
try {
context_.put(pv_name).build([&value](pvxs::Value&& val) {
pvxs::shared_array<int16_t> arr(value.size());
for (size_t i = 0; i < value.size(); ++i) {
arr[i] = value[i];
}
val["value"] = arr.freeze();
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
void ContextWrapper::put(
const std::string& pv_name,
const rust::Vec<rust::String>& value,
double timeout) {
try {
context_.put(pv_name).build([&value](pvxs::Value&& val) {
pvxs::shared_array<std::string> arr(value.size());
for (size_t i = 0; i < value.size(); ++i) {
arr[i] = std::string(value[i]);
}
val["value"] = arr.freeze();
return std::move(val);
}).exec()->wait(timeout);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in put for '") + pv_name + "': " + e.what());
}
}
std::unique_ptr<ValueWrapper> ContextWrapper::info(
const std::string& pv_name,
double timeout) {
try {
auto result = context_.info(pv_name).exec()->wait(timeout);
return std::make_unique<ValueWrapper>(std::move(result));
} catch (const std::exception& e) {
throw PvxsError(std::string("Error in info for '") + pv_name + "': " + e.what());
}
}
std::unique_ptr<RpcWrapper> ContextWrapper::rpc_create(const std::string& pv_name) {
try {
return std::make_unique<RpcWrapper>(context_, pv_name);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error creating RPC for '") + pv_name + "': " + e.what());
}
}
std::unique_ptr<MonitorWrapper> ContextWrapper::monitor(const std::string& pv_name) {
try {
return std::make_unique<MonitorWrapper>(context_, pv_name);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error creating monitor for '") + pv_name + "': " + e.what());
}
}
std::unique_ptr<MonitorBuilderWrapper> ContextWrapper::monitor_builder(const std::string& pv_name) {
try {
return std::make_unique<MonitorBuilderWrapper>(context_, pv_name);
} catch (const std::exception& e) {
throw PvxsError(std::string("Error creating monitor builder for '") + pv_name + "': " + e.what());
}
}
std::unique_ptr<ContextWrapper> create_context_from_env() {
return ContextWrapper::from_env();
}
std::unique_ptr<ValueWrapper> context_get(ContextWrapper& ctx, rust::Str pv_name, double timeout) {
return ctx.get(std::string(pv_name), timeout);
}
void context_put_double(ContextWrapper& ctx, rust::Str pv_name, double value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_int32(ContextWrapper& ctx, rust::Str pv_name, int32_t value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_string(ContextWrapper& ctx, rust::Str pv_name, int32_t value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_string(ContextWrapper& ctx, rust::Str pv_name, rust::String value, double timeout) {
ctx.put(std::string(pv_name), std::string(value), timeout);
}
void context_put_enum(ContextWrapper& ctx, rust::Str pv_name, int16_t value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_double_array(ContextWrapper& ctx, rust::Str pv_name, rust::Vec<double> value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_int32_array(ContextWrapper& ctx, rust::Str pv_name, rust::Vec<int32_t> value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
void context_put_string_array(ContextWrapper& ctx, rust::Str pv_name, rust::Vec<rust::String> value, double timeout) {
ctx.put(std::string(pv_name), value, timeout);
}
std::unique_ptr<ValueWrapper> context_info(ContextWrapper& ctx, rust::Str pv_name, double timeout) {
return ctx.info(std::string(pv_name), timeout);
}
bool value_is_valid(const ValueWrapper& val) {
return val.valid();
}
rust::String value_to_string(const ValueWrapper& val) {
return val.to_string();
}
double value_get_field_double(const ValueWrapper& val, rust::String field_name) {
return val.get_field_double(std::string(field_name));
}
int32_t value_get_field_int32(const ValueWrapper& val, rust::String field_name) {
return val.get_field_int32(std::string(field_name));
}
rust::String value_get_field_string(const ValueWrapper& val, rust::String field_name) {
return val.get_field_string(std::string(field_name));
}
int16_t value_get_field_enum(const ValueWrapper& val, rust::String field_name) {
return val.get_field_enum(std::string(field_name));
}
rust::Vec<double> value_get_field_double_array(const ValueWrapper& val, rust::String field_name) {
return val.get_field_double_array(std::string(field_name));
}
rust::Vec<int32_t> value_get_field_int32_array(const ValueWrapper& val, rust::String field_name) {
return val.get_field_int32_array(std::string(field_name));
}
rust::Vec<int16_t> value_get_field_enum_array(const ValueWrapper& val, rust::String field_name) {
return val.get_field_enum_array(std::string(field_name));
}
rust::Vec<rust::String> value_get_field_string_array(const ValueWrapper& val, rust::String field_name) {
return val.get_field_string_array(std::string(field_name));
}
}