qtty-cpp
Header-only C++ wrapper for qtty
Loading...
Searching...
No Matches
serialization.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <stdexcept>
9#include <string>
10#include <string_view>
11#include <type_traits>
12extern "C" {
13#include "qtty_ffi.h"
14}
15#include "ffi_core.hpp"
16
17// Forward declarations for JSON-related FFI functions. These may not be present
18// in older generated headers; we declare them here to ensure availability at
19// compile time when linking against a serde-enabled qtty-ffi.
20extern "C" {
21int32_t qtty_quantity_to_json_value(qtty_quantity_t src, char** out_json);
22int32_t qtty_quantity_from_json_value(UnitId unit, const char* json, qtty_quantity_t* out);
23int32_t qtty_quantity_to_json(qtty_quantity_t src, char** out_json);
24int32_t qtty_quantity_from_json(const char* json, qtty_quantity_t* out);
25void qtty_string_free(char* s);
26}
27
28namespace qtty {
29namespace serialization {
30
31// Thin wrappers over Rust FFI JSON serialize/deserialize.
32// Requires qtty-ffi to be built with the `serde` Cargo feature.
33
39inline std::string from_owned_c(char* ptr) {
40 if (!ptr) return {};
41 std::string s(ptr);
42 // Free via FFI allocator
44 return s;
45}
46
47// Serialize only the numeric value as a JSON number string.
48// Mirrors Rust's default serde for quantities.
49
56template<typename UnitTag>
57std::string to_json_value(const Quantity<UnitTag>& q) {
60 check_status(status, "Creating source quantity for to_json_value");
61
62 char* out = nullptr;
64 check_status(status, "Serializing value to JSON");
65 return from_owned_c(out);
66}
67
74template<typename T>
83
84// Serialize value and unit_id into an object {"value":<f64>, "unit_id":<u32>}.
85
92template<typename UnitTag>
93std::string to_json(const Quantity<UnitTag>& q) {
96 check_status(status, "Creating source quantity for to_json");
97
98 char* out = nullptr;
100 check_status(status, "Serializing quantity to JSON");
101 return from_owned_c(out);
102}
103
105 // cbindgen exposes UnitId directly; cast is safe for values from Rust
106 return static_cast<UnitId>(raw);
107}
108
109// Parse {"value":<f64>, "unit_id":<u32>} and construct a typed quantity.
110// Rejects mismatched dimensions and unknown unit_ids at the Rust boundary.
111
118template<typename T>
120 using UnitTag = typename ExtractTag<T>::type;
123 check_status(status, "Deserializing quantity from JSON");
124
125 // Convert to requested UnitTag if needed; Rust returns the unit in JSON
129 check_status(status, "Converting deserialized quantity to target unit");
131 }
133}
134
135} // namespace serialization
136} // namespace qtty
constexpr double value() const
Definition ffi_core.hpp:152
Core quantity template and error translation utilities.
Quantity< typename ExtractTag< T >::type > from_json_value(std::string_view json)
Deserialize a JSON numeric value into a typed quantity.
std::string to_json(const Quantity< UnitTag > &q)
Serialize a typed quantity as JSON object with value and unit id.
std::string to_json_value(const Quantity< UnitTag > &q)
Serialize only the numeric value as JSON for a typed quantity.
UnitId unit_id_from_u32(uint32_t raw)
Quantity< typename ExtractTag< T >::type > from_json(std::string_view json)
Deserialize a JSON quantity object into a requested target type.
std::string from_owned_c(char *ptr)
Convert an owned C string from FFI into std::string and free it.
void check_status(int32_t status, const char *operation)
Convert qtty FFI status codes into typed C++ exceptions.
Definition ffi_core.hpp:72
int32_t qtty_quantity_from_json_value(UnitId unit, const char *json, qtty_quantity_t *out)
void qtty_string_free(char *s)
int32_t qtty_quantity_from_json(const char *json, qtty_quantity_t *out)
int32_t qtty_quantity_to_json_value(qtty_quantity_t src, char **out_json)
int32_t qtty_quantity_to_json(qtty_quantity_t src, char **out_json)