A11 (C++ runtime)
Native C++ implementation of the A11 streaming action runtime
Loading...
Searching...
No Matches
values.h
Go to the documentation of this file.
1/*
2 * Copyright 2026 The A11 Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef A11_FLOW_VALUES_H_
18#define A11_FLOW_VALUES_H_
19
20#include <cstddef>
21#include <cstdint>
22#include <memory>
23#include <optional>
24#include <string>
25#include <string_view>
26#include <utility>
27#include <vector>
28
29#include <absl/base/nullability.h>
30#include <absl/container/flat_hash_map.h>
31#include <absl/status/status.h>
32#include <absl/status/statusor.h>
33#include <absl/time/time.h>
34#include <absl/types/span.h>
35
36#include "a11/data/types.h"
37#include "a11/flow/pattern.h"
38#include "a11/flow/plan.h"
39#include "a11/flow/syntax.h"
40
41namespace a11::flow {
42
43class Value;
44
60 public:
61 virtual ~HostObject() = default;
62
64 [[nodiscard]] virtual std::string Tag() const = 0;
66 [[nodiscard]] virtual std::string Text() const = 0;
68 [[nodiscard]] virtual bool Truthy() const = 0;
70 [[nodiscard]] virtual std::optional<size_t> Size() const = 0;
74 [[nodiscard]] virtual Value Field(std::string_view name) const = 0;
76 [[nodiscard]] virtual Value Element(const Value& key) const = 0;
78 [[nodiscard]] virtual bool Equals(const HostObject& other) const = 0;
79};
80
89class Value {
90 public:
91 enum class Kind {
95 kNull,
96 kBool,
98 kDouble,
99 kString,
100 kBytes,
101 kList,
102 kObject,
103 kDuration,
104 kTime,
107 kChunk,
108 kHost,
109 };
110
116 using Pairs = std::vector<std::pair<std::string, Value>>;
117
118 Value() = default;
119
120 static Value Null() { return {}; }
121
122 static Value Bool(bool value);
123 static Value Integer(std::int64_t value);
124 static Value Double(double value);
125 static Value String(std::string value);
127 static Value List(std::vector<Value> items);
128 static Value Object(Pairs pairs);
129 static Value Duration(absl::Duration value);
130 static Value Time(absl::Time value);
132 static Value Host(std::shared_ptr<const HostObject> object);
134 static Value Of(const syntax::Constant& constant);
135
136 [[nodiscard]] Kind kind() const { return kind_; }
137
138 [[nodiscard]] bool IsNull() const { return kind_ == Kind::kNull; }
139
140 [[nodiscard]] bool IsNumber() const {
141 return kind_ == Kind::kInteger || kind_ == Kind::kDouble;
142 }
143
144 [[nodiscard]] bool IsTimelike() const {
145 return kind_ == Kind::kDuration || kind_ == Kind::kTime;
146 }
147
150 [[nodiscard]] bool IsTextlike() const {
151 return kind_ == Kind::kString || kind_ == Kind::kBytes;
152 }
153
154 [[nodiscard]] bool boolean() const { return boolean_; }
155
156 [[nodiscard]] std::int64_t integer() const { return integer_; }
157
158 [[nodiscard]] double number() const { return number_; }
159
160 [[nodiscard]] const std::string& text() const { return *text_; }
161
162 [[nodiscard]] const std::vector<Value>& items() const { return *items_; }
163
164 [[nodiscard]] const Pairs& pairs() const { return *pairs_; }
165
166 [[nodiscard]] absl::Duration duration() const { return duration_; }
167
168 [[nodiscard]] absl::Time time() const { return time_; }
169
170 [[nodiscard]] const data::Chunk& chunk() const { return *chunk_; }
171
172 [[nodiscard]] const HostObject& host() const { return *host_; }
173
174 [[nodiscard]] const std::shared_ptr<const HostObject>& host_object() const {
175 return host_;
176 }
177
179 [[nodiscard]] const Value* absl_nullable Get(std::string_view key) const;
180
182 friend bool operator==(const Value& left, const Value& right);
183
184 private:
185 Kind kind_ = Kind::kNull;
186 bool boolean_ = false;
187 std::int64_t integer_ = 0;
188 double number_ = 0.0;
189 absl::Duration duration_;
190 absl::Time time_;
191 std::shared_ptr<const std::string> text_;
192 std::shared_ptr<const std::vector<Value>> items_;
193 std::shared_ptr<const Pairs> pairs_;
194 std::shared_ptr<const data::Chunk> chunk_;
195 std::shared_ptr<const HostObject> host_;
196};
197
207 public:
208 virtual ~HostBridge() = default;
209
214 virtual absl::StatusOr<Value> Coerce(std::string_view tag,
215 const Value& value) = 0;
216
218 virtual absl::StatusOr<Value> FromChunk(const data::Chunk& chunk) = 0;
219
221 virtual absl::StatusOr<data::Chunk> ToChunk(const Value& value,
222 std::string_view mimetype) = 0;
223
237 virtual std::vector<absl::StatusOr<Value>> FromChunks(
238 absl::Span<const data::Chunk* const> chunks) {
239 std::vector<absl::StatusOr<Value>> values;
240 values.reserve(chunks.size());
241 for (const data::Chunk* chunk : chunks) {
242 {
243 values.push_back(FromChunk(*chunk));
244 }
245 }
246 return values;
247 }
248
252 virtual std::vector<absl::StatusOr<data::Chunk>> ToChunks(
253 absl::Span<const Value* const> values, std::string_view mimetype) {
254 std::vector<absl::StatusOr<data::Chunk>> chunks;
255 chunks.reserve(values.size());
256 for (const Value* value : values) {
257 chunks.push_back(ToChunk(*value, mimetype));
258 }
259 return chunks;
260 }
261
262 // How this host would rather hold a value of a shape the *language* declared.
280 virtual absl::StatusOr<Value> Adopt(const DtoPlan& shape,
281 const Program& program,
282 const Value& value) {
283 (void)shape;
284 (void)program;
285 return value;
286 }
287};
288
294std::unique_ptr<HostBridge> NativeHostBridge();
295
296// --- Reading values ----------------------------------------------------------
297
303Value Lookup(const Value& value, const Value& key);
304
306bool Truthy(const Value& value);
307
313int Order(const Value& left, const Value& right);
314
320absl::StatusOr<Value> Add(const Value& left, const Value& right);
321
323std::string AsText(const Value& value);
324
328Value AsNumber(const Value& value);
329
340absl::StatusOr<Value> MatchPattern(std::string_view pattern,
341 std::string_view subject);
342
348Value MatchCompiled(const pattern::Pattern& pattern, std::string_view subject);
349
351double AsDouble(const Value& value);
352
354Value AsJson(const Value& value);
355
357Value Truncate(const Value& value, std::int64_t size);
358
364std::string JsonText(const Value& value);
365
366// --- Times and durations -----------------------------------------------------
367
373double DurationSeconds(absl::Duration value);
374
380absl::Duration SecondsDuration(double total);
381
388std::optional<absl::Duration> ParseDuration(std::string_view text);
389
391absl::Duration AsDuration(const Value& value);
392
394absl::Time AsTime(const Value& value);
395
397std::optional<absl::Time> ParseTime(std::string_view text);
398
400std::string DurationText(absl::Duration value, std::string_view spec = {});
401
403std::string TimeText(absl::Time value, std::string_view spec = {});
404
405// --- Formatting --------------------------------------------------------------
406
419std::string Strformat(const Value& format, absl::Span<const Value> arguments);
420
421// --- Evaluation --------------------------------------------------------------
422
431 HostBridge* absl_nullable bridge = nullptr;
432 const Program* absl_nullable shapes = nullptr;
433};
434
443 const absl::flat_hash_map<const syntax::Node*, Value>* absl_nullable bound =
444 nullptr;
447 bool has_it = false;
448 HostBridge* absl_nullable bridge = nullptr;
450 const Program* absl_nullable shapes = nullptr;
451
452 [[nodiscard]] CoerceContext Coercion() const { return {bridge, shapes}; }
453};
454
461absl::StatusOr<Value> Evaluate(const syntax::Node& node,
462 const EvalContext& context);
463
470absl::StatusOr<Value> Coerce(const Value& value,
471 const syntax::TypeExpression& type,
472 const CoerceContext& context);
473
474// Make `value` a value of `shape`: fill its defaults, check its bounds, and
475// coerce every field to the type the shape gives it.
490absl::StatusOr<Value> CoerceShape(const DtoPlan& shape, const Value& value,
491 const CoerceContext& context);
492
497absl::StatusOr<Value> CallBuiltin(std::string_view name,
498 absl::Span<const Value> arguments,
499 HostBridge* absl_nullable bridge);
500
501// --- Statuses as data --------------------------------------------------------
502
508Value StatusRecord(const absl::Status& status);
509
511absl::Status StatusOfRecord(const Value& record);
512
518std::optional<absl::StatusCode> StatusCodeOf(const Value& value);
519
520} // namespace a11::flow
521
522#endif // A11_FLOW_VALUES_H_
What the process running a flow knows and the language does not.
Definition values.h:206
virtual std::vector< absl::StatusOr< data::Chunk > > ToChunks(absl::Span< const Value *const > values, std::string_view mimetype)
Chunks holding values, in order, each with its own outcome.
Definition values.h:252
virtual absl::StatusOr< Value > Coerce(std::string_view tag, const Value &value)=0
Make value a value of the type tag names.
virtual ~HostBridge()=default
virtual std::vector< absl::StatusOr< Value > > FromChunks(absl::Span< const data::Chunk *const > chunks)
The values a batch of chunks holds, in order, each with its own outcome.
Definition values.h:237
virtual absl::StatusOr< Value > FromChunk(const data::Chunk &chunk)=0
The value chunk holds.
virtual absl::StatusOr< data::Chunk > ToChunk(const Value &value, std::string_view mimetype)=0
A chunk holding value, in mimetype when one is asked for.
virtual absl::StatusOr< Value > Adopt(const DtoPlan &shape, const Program &program, const Value &value)
How this host would rather hold a value of a shape the language declared.
Definition values.h:280
A value only the host knows what to do with.
Definition values.h:59
virtual bool Truthy() const =0
Whether the value counts as true.
virtual Value Field(std::string_view name) const =0
value.name, or a null value when there is no such field.
virtual std::string Tag() const =0
The tag the host knows this type by, for a message.
virtual ~HostObject()=default
virtual std::optional< size_t > Size() const =0
How many things it holds, where that means anything.
virtual Value Element(const Value &key) const =0
value[key].
virtual bool Equals(const HostObject &other) const =0
Whether this is the same value as other, by the host's own equality.
virtual std::string Text() const =0
What as_text gives: what the value is on the wire, not its repr.
One Flow value.
Definition values.h:89
static Value Null()
Definition values.h:120
static Value Bool(bool value)
Definition values.cc:420
const std::vector< Value > & items() const
Definition values.h:162
static Value List(std::vector< Value > items)
Definition values.cc:455
static Value Bytes(data::Bytes value)
Definition values.cc:448
const std::shared_ptr< const HostObject > & host_object() const
Definition values.h:174
std::int64_t integer() const
Definition values.h:156
static Value Object(Pairs pairs)
Definition values.cc:462
const HostObject & host() const
Definition values.h:172
Kind kind() const
Definition values.h:136
const Value *absl_nullable Get(std::string_view key) const
The value at key of an object, or nullptr.
Definition values.cc:534
static Value String(std::string value)
Definition values.cc:441
bool IsTimelike() const
Definition values.h:144
const Pairs & pairs() const
Definition values.h:164
bool IsNumber() const
Definition values.h:140
double number() const
Definition values.h:158
static Value Integer(std::int64_t value)
Definition values.cc:427
static Value Double(double value)
Definition values.cc:434
bool boolean() const
Definition values.h:154
const std::string & text() const
Definition values.h:160
static Value Host(std::shared_ptr< const HostObject > object)
Definition values.cc:490
static Value Of(const syntax::Constant &constant)
The value a Constant – a literal, or a folded literal expression – is.
Definition values.cc:500
Kind
Definition values.h:91
@ kChunk
An undecoded chunk, kept whole so a pipe that only moves values re-writes the producer's own bytes an...
@ kNull
A value that is not there: an absent key, an empty stream, a missing header.
absl::Duration duration() const
Definition values.h:166
bool IsTextlike() const
Whether the value is one the language itself can take apart: a string or a byte string,...
Definition values.h:150
friend bool operator==(const Value &left, const Value &right)
Whether the two values are equal, as == in a flow decides it.
Definition values.cc:546
const data::Chunk & chunk() const
Definition values.h:170
bool IsNull() const
Definition values.h:138
absl::Time time() const
Definition values.h:168
static Value Chunk(data::Chunk chunk)
Definition values.cc:483
std::vector< std::pair< std::string, Value > > Pairs
The pairs of an object, in the order they were written.
Definition values.h:116
std::string value
Definition discover.cc:114
std::string key
Definition discover.cc:782
std::optional< std::string > text
The text, where the value is a string literal or a name bound to one.
Definition discover.cc:612
std::string type
The type and what follows it: string required, list[a11.Chunk] stream.
Definition format.cc:51
std::string name
The name and its colon, which travel together because they always do.
Definition format.cc:49
std::vector< std::string > arguments
argv for the program, [0] = path.
Definition main.cc:134
std::string Bytes
Raw byte payload; an alias of std::string.
Definition types.h:56
Definition boundary.cc:32
absl::Duration SecondsDuration(double total)
A duration of total seconds, negative ones included.
Definition values.cc:914
double DurationSeconds(absl::Duration value)
A duration as a number of seconds, for every duration there is.
Definition values.cc:904
Value StatusRecord(const absl::Status &status)
A status as the record a flow sees when it looks at an outcome.
Definition values.cc:2229
absl::StatusOr< Value > CallBuiltin(std::string_view name, absl::Span< const Value > arguments, HostBridge *absl_nullable bridge)
Call one of the language's fixed functions.
Definition values.cc:1328
Value MatchCompiled(const pattern::Pattern &compiled, std::string_view subject)
The same, against a pattern already compiled.
Definition values.cc:798
std::optional< absl::StatusCode > StatusCodeOf(const Value &value)
The canonical code value names, by name or by number, or nullopt.
Definition values.cc:2242
absl::StatusOr< Value > Evaluate(const syntax::Node &node, const EvalContext &context)
Evaluate one expression.
Definition values.cc:2075
absl::StatusOr< Value > Add(const Value &left, const Value &right)
left + right, as an expression means it.
Definition values.cc:2068
std::unique_ptr< HostBridge > NativeHostBridge()
A bridge over A11's own C++ serialisation registry.
Definition values.cc:593
Value AsJson(const Value &value)
Text parsed as JSON; anything already decoded is left alone.
Definition values.cc:824
absl::StatusOr< Value > MatchPattern(std::string_view text, std::string_view subject)
The fields a pattern pulls out of subject, or null where it does not fit.
Definition values.cc:788
std::string DurationText(absl::Duration value, std::string_view spec)
A duration as text: 1m30s by default, or one unit when spec names one.
Definition values.cc:1048
double AsDouble(const Value &value)
AsNumber as a double, for the places that only want the magnitude.
Definition values.cc:756
Value Lookup(const Value &value, const Value &key)
Take key out of value: a mapping key, an index, or a field.
Definition values.cc:599
std::optional< absl::Time > ParseTime(std::string_view text)
An instant from RFC 3339 text, as TimeText writes it.
Definition values.cc:1010
std::string JsonText(const Value &value)
A value's own JSON text, as json.dumps(sort_keys=True) writes it.
Definition values.cc:896
absl::StatusOr< Value > CoerceShape(const DtoPlan &shape, const Value &value, const CoerceContext &context)
Make value a value of shape: fill its defaults, check its bounds, and coerce every field to the type ...
Definition values.cc:1875
int Order(const Value &left, const Value &right)
Where two values sit relative to one another: -1, 0 or 1.
Definition values.cc:2064
std::optional< absl::Duration > ParseDuration(std::string_view text)
A duration from the way the language writes one, or nullopt.
Definition values.cc:921
Value AsNumber(const Value &value)
value as a number, or zero when there is nothing to read.
Definition values.cc:695
absl::Duration AsDuration(const Value &value)
A duration from a duration, from written text, or from seconds.
Definition values.cc:997
bool Truthy(const Value &value)
Whether value counts as true, as an if and a where decide it.
Definition values.cc:638
absl::StatusOr< Value > Coerce(const Value &value, const syntax::TypeExpression &type, const CoerceContext &context)
Make value a value of the type type names.
Definition values.cc:1921
std::string Strformat(const Value &format, absl::Span< const Value > arguments)
format with each % conversion replaced by one of arguments.
Definition values.cc:1187
absl::Status StatusOfRecord(const Value &record)
The status a record like the one above describes.
Definition values.cc:2271
std::string AsText(const Value &value)
value as text, the way the text stage and builtin render it.
Definition values.cc:664
absl::Time AsTime(const Value &value)
An instant from an instant, from RFC 3339 text, or from epoch seconds.
Definition values.cc:1035
Value Truncate(const Value &value, std::int64_t size)
The first size of a value: characters, bytes, elements or pairs.
Definition values.cc:869
std::string TimeText(absl::Time value, std::string_view spec)
An instant as text: RFC 3339 in UTC, a strftime pattern, or epoch.
Definition values.cc:1092
absl::Duration Duration
A11 duration; an alias of absl::Duration (nanosecond-aware).
Definition time.h:40
absl::Time Time
A11 instant; an alias of absl::Time (nanosecond-aware).
Definition time.h:42
std::string subject
What to call it in the message: ‘'Source’, orthe pattern`.
Definition resolve.cc:3580
std::string shape
The shape this stream's values are, where the flow said so: a port typed with a struct,...
Definition resolve.cc:715
graph::RefId node
The graph ref this answer corresponds to, when a graph is being built.
Definition resolve.cc:698
std::string mimetype
Definition sqlite_chunk_store.cc:191
A unit of data: bytes plus optional descriptive metadata.
Definition types.h:185
What coercion needs besides the value and the type.
Definition values.h:430
const Program *absl_nullable shapes
Definition values.h:432
HostBridge *absl_nullable bridge
Definition values.h:431
One compiled struct: a shape a port may be typed with.
Definition plan.h:80
What an expression is evaluated against.
Definition values.h:442
HostBridge *absl_nullable bridge
Definition values.h:448
const absl::flat_hash_map< const syntax::Node *, Value > *absl_nullable bound
Definition values.h:443
const Program *absl_nullable shapes
The shapes the program declared, for a cast written inside an expression.
Definition values.h:450
bool has_it
Definition values.h:447
Value it
The value a where/map/group stage is looking at.
Definition values.h:446
CoerceContext Coercion() const
Definition values.h:452
Every flow and shape one source file declares.
Definition plan.h:185
A value the language can write out in full: what a literal is, and what folding a literal expression ...
Definition syntax.h:80
Output format
Definition main.cc:64
A11's core wire value types: chunks, node fragments and messages.