morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
value.hpp File Reference

The UI document's typed values (ui::Value), its types (ui::Type), their JSON form, and ui::Refusal, the error every load-time check of the document layer returns. More...

#include <algorithm>
#include <array>
#include <compare>
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <functional>
#include <glaze/glaze.hpp>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>
#include "../util/datetime.hpp"
#include "../util/rational.hpp"

Go to the source code of this file.

Classes

struct  morph::ui::Refusal
 Why a document, an expression or a value was refused: where, and the reason. More...
struct  morph::ui::Decimal
 An exact decimal: a math::Rational whose DecimalPlaces are the value's declared places. More...
struct  morph::ui::Quantity
 An exact decimal with a unit: the id of a unit of the server's unit systems (x-unitAlternatives). More...
class  morph::ui::Value
 The document's typed value (spec 5 §3): what every expression evaluates to. More...
struct  morph::ui::Type
 A document type (spec 5 §3): a kind, whether null is allowed, and a list's element type. More...

Typedefs

using morph::ui::Json = glz::generic_u64
 The JSON tree the document layer reads and writes: glaze's generic value in its integer-preserving mode, so an integer is never read through a double.
using morph::ui::ValueList = std::vector<Value>
 A list value.
using morph::ui::ValueRecord = std::map<std::string, Value, std::less<>>
 A record value: field name to value, ordered by name.

Enumerations

enum class  morph::ui::ValueKind : std::uint8_t {
  Null , Bool , Int , String ,
  Decimal , Quantity , Timestamp , List ,
  Record
}
 The kinds a Value holds. More...
enum class  morph::ui::TypeKind : std::uint8_t {
  Any , Bool , Int , String ,
  Decimal , Quantity , Timestamp , Key ,
  Record , List
}
 The kinds of a Type. More...

Functions

std::string morph::ui::pointerAppend (std::string_view base, std::string_view token)
 Appends one reference token to a JSON Pointer, escaping ~ and / as RFC 6901 requires.
std::string morph::ui::pointerAppend (std::string_view base, std::size_t index)
 Appends an array index to a JSON Pointer.
constexpr std::string_view morph::ui::kindName (ValueKind kind)
 The name of a value kind, as a document spells its type.
std::expected< Type, std::string > morph::ui::detail::parseTypePrefix (std::string_view &text, int depth)
 Parses one type at the front of text, advancing it.
std::expected< Type, std::string > morph::ui::parseType (std::string_view text)
 Parses a document type: bool, int, string, decimal, quantity, timestamp, key, record, any, list<T>, each optionally followed by ?.
std::optional< std::int64_t > morph::ui::detail::jsonInt (Json const &json) noexcept
 Reads a JSON integer as an int64.
std::optional< std::expected< Value, std::string > > morph::ui::detail::exactFromJson (Json::object_t const &object)
 Reads the wire form of a decimal or quantity: an object of exactly num, den, dp (and unit).
std::expected< Value, std::string > morph::ui::valueFromJson (Json const &json)
 Reads a value from its JSON form, structurally.
std::expected< Value, std::string > morph::ui::valueFromJson (Json const &json, Type const &type)
 Reads a value from its JSON form as a value of type.
Json morph::ui::valueToJson (Value const &value)
 Writes a value in its JSON form: the inverse of valueFromJson, with a timestamp as ISO-8601 text.
bool morph::ui::detail::nestsTooDeep (std::string_view text)
 Whether JSON text nests objects and arrays deeper than kMaxJsonDepth.
std::expected< Json, std::string > morph::ui::parseJson (std::string_view text)
 Parses JSON text into the document layer's JSON tree.

Variables

constexpr std::size_t morph::ui::kMaxJsonDepth = 64
 The deepest a document's JSON may nest, counting each object and array as one level.

Detailed Description

The UI document's typed values (ui::Value), its types (ui::Type), their JSON form, and ui::Refusal, the error every load-time check of the document layer returns.

Specified in docs/spec/ui/document.md, "Values and types".

Definition in file value.hpp.

Typedef Documentation

◆ Json

using morph::ui::Json = glz::generic_u64

The JSON tree the document layer reads and writes: glaze's generic value in its integer-preserving mode, so an integer is never read through a double.

Definition at line 35 of file value.hpp.

◆ ValueList

using morph::ui::ValueList = std::vector<Value>

A list value.

Definition at line 126 of file value.hpp.

◆ ValueRecord

using morph::ui::ValueRecord = std::map<std::string, Value, std::less<>>

A record value: field name to value, ordered by name.

Definition at line 129 of file value.hpp.

Enumeration Type Documentation

◆ ValueKind

enum class morph::ui::ValueKind : std::uint8_t
strong

The kinds a Value holds.

Enumerator
Null 

No value: absent, not entered, or the result of an error.

Bool 

bool.

Int 

int: a 64-bit signed integer, exact.

String 

string: UTF-8 text.

Decimal 

decimal: an exact rational with declared places.

Quantity 

quantity: a decimal with a unit.

Timestamp 

timestamp: a UTC instant with millisecond precision.

List 

list<T>.

Record 

A record of named fields.

Definition at line 132 of file value.hpp.

◆ TypeKind

enum class morph::ui::TypeKind : std::uint8_t
strong

The kinds of a Type.

Enumerator
Any 

Not known to the document: a query result, a reply, an element's value.

Bool 

bool.

Int 

int.

String 

string.

Decimal 

decimal.

Quantity 

quantity.

Timestamp 

timestamp.

Key 

key: an int or a string.

Record 

record: a record whose fields the document does not declare.

List 

list<T>.

Definition at line 294 of file value.hpp.

Function Documentation

◆ pointerAppend() [1/2]

std::string morph::ui::pointerAppend ( std::string_view base,
std::string_view token )
inlinenodiscard

Appends one reference token to a JSON Pointer, escaping ~ and / as RFC 6901 requires.

Parameters
baseThe pointer to extend, "" for the root.
tokenThe object key to append.
Returns
base + "/" + escaped(token).

Definition at line 68 of file value.hpp.

◆ pointerAppend() [2/2]

std::string morph::ui::pointerAppend ( std::string_view base,
std::size_t index )
inlinenodiscard

Appends an array index to a JSON Pointer.

Parameters
baseThe pointer to extend, "" for the root.
indexThe array index to append.
Returns
base + "/" + index.

Definition at line 87 of file value.hpp.

◆ kindName()

std::string_view morph::ui::kindName ( ValueKind kind)
nodiscardconstexpr

The name of a value kind, as a document spells its type.

Parameters
kindThe kind.
Returns
null, bool, int, string, decimal, quantity, timestamp, list or record.

Definition at line 147 of file value.hpp.

◆ parseTypePrefix()

std::expected< Type, std::string > morph::ui::detail::parseTypePrefix ( std::string_view & text,
int depth )
inlinenodiscard

Parses one type at the front of text, advancing it.

Parameters
textThe remaining text; on success, what follows the type.
depthThe list<> nesting depth so far, bounded so a hostile type cannot recurse without limit.
Returns
The type, or the reason it does not parse.

Definition at line 419 of file value.hpp.

◆ parseType()

std::expected< Type, std::string > morph::ui::parseType ( std::string_view text)
inlinenodiscard

Parses a document type: bool, int, string, decimal, quantity, timestamp, key, record, any, list<T>, each optionally followed by ?.

Parameters
textThe type as written.
Returns
The type, or the reason it does not parse.

Definition at line 479 of file value.hpp.

◆ jsonInt()

std::optional< std::int64_t > morph::ui::detail::jsonInt ( Json const & json)
inlinenodiscardnoexcept

Reads a JSON integer as an int64.

Parameters
jsonThe JSON value.
Returns
The integer; std::nullopt when it is not an integer or does not fit int64.

Definition at line 496 of file value.hpp.

◆ exactFromJson()

std::optional< std::expected< Value, std::string > > morph::ui::detail::exactFromJson ( Json::object_t const & object)
inlinenodiscard

Reads the wire form of a decimal or quantity: an object of exactly num, den, dp (and unit).

Parameters
objectThe JSON object.
Returns
The value when object has that shape; std::nullopt when it is some other record; the reason when it has the shape and a bad member.

Definition at line 512 of file value.hpp.

◆ valueFromJson() [1/2]

std::expected< Value, std::string > morph::ui::valueFromJson ( Json const & json)
inlinenodiscard

Reads a value from its JSON form, structurally.

null, booleans, integers, strings, arrays and objects map to their kinds. An object of exactly num, den and dp is a decimal, and with unit a quantity: the wire form of math::Rational. A number with a fraction or an exponent is refused, because an exact value is never written as a double; an integer beyond int64 is refused. A timestamp has no structural form — it is a string — so it is read through the typed overload.

Parameters
jsonThe JSON value.
Returns
The value, or the reason it is refused.

Definition at line 570 of file value.hpp.

◆ valueFromJson() [2/2]

std::expected< Value, std::string > morph::ui::valueFromJson ( Json const & json,
Type const & type )
inlinenodiscard

Reads a value from its JSON form as a value of type.

A timestamp is read from its ISO-8601 text; an int given for a decimal becomes a decimal of zero places; a list's elements are read as its element type. The result must then conform to type.

Parameters
jsonThe JSON value.
typeThe type the value must have.
Returns
The value, or the reason it is refused.

Definition at line 625 of file value.hpp.

◆ valueToJson()

Json morph::ui::valueToJson ( Value const & value)
inlinenodiscard

Writes a value in its JSON form: the inverse of valueFromJson, with a timestamp as ISO-8601 text.

Parameters
valueThe value.
Returns
The JSON value.

Definition at line 668 of file value.hpp.

◆ nestsTooDeep()

bool morph::ui::detail::nestsTooDeep ( std::string_view text)
inlinenodiscard

Whether JSON text nests objects and arrays deeper than kMaxJsonDepth.

Parameters
textThe JSON text; brackets inside string literals do not count.
Returns
True when some point of the text is inside more than kMaxJsonDepth objects and arrays.

Definition at line 721 of file value.hpp.

◆ parseJson()

std::expected< Json, std::string > morph::ui::parseJson ( std::string_view text)
inlinenodiscard

Parses JSON text into the document layer's JSON tree.

Parameters
textThe JSON text.
Returns
The tree, or the reason the text is not JSON or nests deeper than kMaxJsonDepth.

Definition at line 752 of file value.hpp.

Variable Documentation

◆ kMaxJsonDepth

std::size_t morph::ui::kMaxJsonDepth = 64
inlineconstexpr

The deepest a document's JSON may nest, counting each object and array as one level.

Documents written by hand or by the builders nest a dozen levels or so. The bound is checked before the JSON parser runs, because the parser and every later pass over the tree descend recursively, and a hostile document nested a few hundred levels deep overflows a 1 MB thread stack before anything else can refuse it.

Definition at line 714 of file value.hpp.