15#ifndef A11_DATA_SERIALIZATION_H_
16#define A11_DATA_SERIALIZATION_H_
28#include <absl/base/nullability.h>
29#include <absl/status/status.h>
30#include <absl/status/statusor.h>
65 using Serializer = std::function<absl::StatusOr<Chunk>(
const T&)>;
82 return absl::InvalidArgumentError(
"serializer must be callable");
84 return RegisterSerializerErased(
85 typeid(
T), std::move(type_name), std::move(mimetype),
86 [serializer = std::move(serializer)](
87 const void*
absl_nonnull value) -> absl::StatusOr<Chunk> {
88 if (value ==
nullptr) {
89 return absl::InvalidArgumentError(
"serializer value is null");
92 return serializer(*
static_cast<const T*
>(value));
93 }
catch (
const std::exception& error) {
94 return absl::UnknownError(error.what());
96 return absl::UnknownError(
97 "serializer raised a non-standard exception");
109 template <
typename T>
113 return absl::InvalidArgumentError(
"deserializer must be callable");
115 return RegisterDeserializerErased(
116 typeid(
T), std::move(type_name), std::move(mimetype),
117 [deserializer = std::move(deserializer)](
118 const Chunk& chunk) -> absl::StatusOr<std::any> {
120 absl::StatusOr<T> result = deserializer(chunk);
122 return result.status();
123 return std::any(std::move(*result));
124 }
catch (
const std::exception& error) {
125 return absl::UnknownError(error.what());
127 return absl::UnknownError(
128 "deserializer raised a non-standard exception");
145 template <
typename T>
146 absl::Status
Register(std::string type_name, std::string mimetype,
149 absl::Status status =
154 std::move(deserializer));
156 RemoveSerializer(
typeid(
T), type_name, mimetype);
159 return absl::OkStatus();
170 template <
typename T>
172 std::string_view mimetype = {})
const {
173 return ToChunkErased(
typeid(
T), &value, mimetype);
185 template <
typename T>
189 absl::StatusOr<std::any> result =
192 return result.status();
194 return std::any_cast<T>(std::move(*result));
195 }
catch (
const std::bad_any_cast& error) {
196 return absl::InternalError(error.what());
208 using ErasedSerializer =
209 std::function<absl::StatusOr<Chunk>(
const void*
absl_nonnull value)>;
210 using ErasedDeserializer =
211 std::function<absl::StatusOr<std::any>(
const Chunk& chunk)>;
213 struct SerializerRegistration;
214 struct DeserializerRegistration;
217 static constexpr size_t kImplSize = 192;
218 static constexpr size_t kImplAlignment =
alignof(std::max_align_t);
223 absl::Status RegisterSerializerErased(std::type_index type,
224 std::string type_name,
225 std::string mimetype,
226 ErasedSerializer serializer);
227 absl::Status RegisterDeserializerErased(std::type_index type,
228 std::string type_name,
229 std::string mimetype,
230 ErasedDeserializer deserializer);
231 void RemoveSerializer(std::type_index type, std::string_view type_name,
232 std::string_view mimetype);
234 absl::StatusOr<Chunk> ToChunkErased(std::type_index type,
236 std::string_view mimetype)
const;
237 absl::StatusOr<std::any> FromChunkErased(
241 alignas(kImplAlignment) std::byte impl_[kImplSize];
A registry of serializers and deserializers indexed by type and MIME.
Definition serialization.h:50
absl::Status RegisterDefaults()
Installs the standard JSON and MessagePack codecs.
Definition serialization.cc:489
size_t serializer_count() const
Number of registered serializers.
Definition serialization.cc:520
std::function< absl::StatusOr< Chunk >(const T &)> Serializer
Callable turning a T into a Chunk.
Definition serialization.h:65
absl::Status Register(std::string type_name, std::string mimetype, Serializer< T > serializer, Deserializer< T > deserializer)
Atomically registers a serializer/deserializer pair for T.
Definition serialization.h:146
absl::Status RegisterDeserializer(std::string type_name, std::string mimetype, Deserializer< T > deserializer)
Registers a deserializer for type T and an exact media type.
Definition serialization.h:110
SerializationRegistry & operator=(const SerializationRegistry &)=delete
std::function< absl::StatusOr< T >(const Chunk &)> Deserializer
Callable reconstructing a T from a Chunk.
Definition serialization.h:69
absl::StatusOr< Chunk > ToChunk(const T &value, std::string_view mimetype={}) const
Serializes value into a Chunk.
Definition serialization.h:171
size_t deserializer_count() const
Number of registered deserializers.
Definition serialization.cc:526
absl::Status RegisterSerializer(std::string type_name, std::string mimetype, Serializer< T > serializer)
Registers a serializer for type T and an exact media type.
Definition serialization.h:79
~SerializationRegistry()
Definition serialization.cc:233
absl::StatusOr< T > FromChunk(const Chunk &chunk, const std::vector< std::string > &mimetype_patterns={}) const
Deserializes chunk into a value of type T.
Definition serialization.h:186
SerializationRegistry(const SerializationRegistry &)=delete
constexpr std::string_view kJsonMimetype
Media type of the built-in JSON codec.
Definition serialization.h:37
SerializationRegistry & GlobalSerializationRegistry()
Returns the process-wide registry (defaults pre-installed).
Definition serialization.cc:532
constexpr std::string_view kMsgpackMimetype
Media type of the built-in MessagePack codec.
Definition serialization.h:39
Future< T > SubmitWithCancellationHook(absl::AnyInvocable< absl::StatusOr< T >() && > work, std::function< void()> cancellation_hook, thread::TreeOptions tree_options)
Run work on A11's fiber pool with application-specific cancellation.
Definition executor.h:30
A unit of data: bytes plus optional descriptive metadata.
Definition types.h:95
A11's core wire value types: chunks, node fragments and messages.