FastLED 3.10.8
Loading...
Searching...
No Matches
json_arg_converter.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/json.h"
4#include "fl/stl/stdint.h"
5#include "fl/stl/string.h"
6#include "fl/stl/tuple.h"
10#include "fl/stl/span.h"
11#include "fl/stl/noexcept.h"
12
13namespace fl {
14
15// Type mapper for RPC parameters:
16// - const char* / char* → ConstCharPtrWrapper (stores string, converts to ptr)
17// - span<const T> → ConstSpanWrapper<T> (stores vector, provides span view)
18// - Other types → strip const/reference
19template <typename T>
23
24template <>
25struct rpc_storage_type<const char*> {
27};
28
29template <>
30struct rpc_storage_type<char*> {
32};
33
34// Specializations for span<const T>
35template <typename T>
36struct rpc_storage_type<fl::span<const T>> {
38};
39
40// Common span specializations for explicit types
41template <>
42struct rpc_storage_type<fl::span<const int>> {
44};
45
46template <>
47struct rpc_storage_type<fl::span<const float>> {
49};
50
51template <>
52struct rpc_storage_type<fl::span<const double>> {
54};
55
56template <>
57struct rpc_storage_type<fl::span<const fl::string>> {
59};
60
61// =============================================================================
62// JsonArgConverter - Convert JSON array to typed tuple
63// =============================================================================
64
65template <typename Signature>
67
68template <typename R, typename... Args>
69class JsonArgConverter<R(Args...)> {
70public:
71 // Map Args to storage types (handles const char* → ConstCharPtrWrapper)
73 static constexpr fl::size argCount() FL_NO_EXCEPT { return sizeof...(Args); }
74
75 static fl::tuple<args_tuple, TypeConversionResult> convert(const json& jsonArgs) FL_NO_EXCEPT {
77 // Value-init so the early-return branches below (not an array,
78 // arg-count mismatch) don't return an indeterminate tuple —
79 // convertArgs() is the only writer and runs after the bail-outs. #2722
80 args_tuple tuple{};
81
82 if (!jsonArgs.is_array()) {
83 result.setError("arguments must be a JSON array");
84 return fl::make_tuple(tuple, result);
85 }
86
87 fl::size count = jsonArgs.size();
88 if (count != sizeof...(Args)) {
89 result.setError("argument count mismatch: expected " +
90 fl::to_string(static_cast<i64>(sizeof...(Args))) +
91 ", got " + fl::to_string(static_cast<i64>(count)));
92 return fl::make_tuple(tuple, result);
93 }
94
95 convertArgs(jsonArgs, tuple, result, make_index_sequence<sizeof...(Args)>{});
96 return fl::make_tuple(tuple, result);
97 }
98
99private:
100 template <fl::size... Is>
101 static void convertArgs(const json& jsonArgs, args_tuple& tuple,
102 TypeConversionResult& result, index_sequence<Is...>) FL_NO_EXCEPT {
103 // Fold expression equivalent using initializer list
104 int dummy[] = {0, (convertArg<Is>(jsonArgs, tuple, result), 0)...};
105 (void)dummy;
106 }
107
108 template <fl::size I>
109 static void convertArg(const json& jsonArgs, args_tuple& tuple, TypeConversionResult& result) FL_NO_EXCEPT {
110 if (result.hasError()) return;
111
112 // Use the stripped type (no const/ref) for conversion and storage
113 using StorageType = typename fl::tuple_element<I, args_tuple>::type;
114 // C++11 compatible: avoid structured bindings
115 fl::tuple<StorageType, TypeConversionResult> convTuple = detail::JsonToType<StorageType>::convert(jsonArgs[I]);
116 StorageType value = fl::get<0>(convTuple);
117 TypeConversionResult convResult = fl::get<1>(convTuple);
118
119 fl::get<I>(tuple) = value;
120
121 // Add argument index to warnings/errors
122 for (fl::size i = 0; i < convResult.warnings().size(); i++) {
123 result.addWarning("arg " + fl::to_string(static_cast<i64>(I)) + ": " + convResult.warnings()[i]);
124 }
125 if (convResult.hasError()) {
126 result.setError("arg " + fl::to_string(static_cast<i64>(I)) + ": " + convResult.errorMessage());
127 }
128 }
129};
130
131// Specialization for void() - no arguments
132template <typename R>
134public:
135 using args_tuple = fl::tuple<>;
136 static constexpr fl::size argCount() FL_NO_EXCEPT { return 0; }
137
140 // Value-init so the early-return branches below (not an array,
141 // arg-count mismatch) don't return an indeterminate tuple —
142 // convertArgs() is the only writer and runs after the bail-outs. #2722
144
145 if (!jsonArgs.is_array()) {
146 result.setError("arguments must be a JSON array");
147 return fl::make_tuple(tuple, result);
148 }
149
150 if (jsonArgs.size() != 0) {
151 result.setError("argument count mismatch: expected 0, got " +
152 fl::to_string(static_cast<i64>(jsonArgs.size())));
153 }
154
155 return fl::make_tuple(tuple, result);
156 }
157};
158
159} // namespace fl
static constexpr fl::size argCount() FL_NO_EXCEPT
static fl::tuple< args_tuple, TypeConversionResult > convert(const json &jsonArgs) FL_NO_EXCEPT
FastLED's Elegant JSON Library: fl::json
tuple< typename fl::decay< Ts >::type... > make_tuple(Ts &&... args) FL_NO_EXCEPT
Definition tuple.h:106
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
constexpr int type_rank< T >::value
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
string to_string(T value) FL_NO_EXCEPT
Definition string.h:459
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NO_EXCEPT
Definition pair.h:119
typename make_index_sequence_impl< N >::type make_index_sequence
Base definition for an LED controller.
Definition crgb.hpp:179
typename fl::remove_cv< typename fl::remove_reference< T >::type >::type type
fl::i64 i64
Definition stdint.h:221
static fl::tuple< T, TypeConversionResult > convert(const json &j) FL_NO_EXCEPT