JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
path.hpp
Go to the documentation of this file.
1/// \file jsonv/path.hpp
2/// Support for [JSONPath](http://goessner.net/articles/JsonPath/).
3///
4/// Copyright (c) 2014-2020 by Travis Gockel. All rights reserved.
5///
6/// This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
7/// as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
8/// version.
9///
10/// \author Travis Gockel (travis@gockelhut.com)
11#pragma once
12
13#include <jsonv/config.hpp>
15#include <string_view>
16
17#include <concepts>
18#include <iosfwd>
19#include <memory>
20#include <string>
21#include <vector>
22
23namespace jsonv
24{
25
26enum class path_element_kind : unsigned char
27{
28 array_index,
29 object_key,
30};
31
32JSONV_PUBLIC std::ostream& operator<<(std::ostream&, const path_element_kind&);
33
34JSONV_NODISCARD JSONV_PUBLIC std::string to_string(const path_element_kind&);
35
37{
38public:
39 path_element(std::size_t idx);
40 path_element(int idx);
41 path_element(std::string key);
42 path_element(std::string_view key);
43 path_element(const char* key);
45 path_element& operator=(const path_element&);
46 path_element(path_element&&) noexcept;
47 path_element& operator=(path_element&&) noexcept;
48
49 ~path_element() noexcept;
50
52 path_element_kind kind() const;
53
55 std::size_t index() const;
56
58 const std::string& key() const;
59
61 bool operator==(const path_element&) const;
63 bool operator!=(const path_element&) const;
64
65private:
66 union storage
67 {
68 std::size_t index;
69 std::string key;
70
71 storage(std::size_t idx);
72 storage(std::string&& key);
73 ~storage() noexcept;
74 };
75
76private:
77 path_element_kind _kind;
78 storage _data;
79};
80
81JSONV_PUBLIC std::ostream& operator<<(std::ostream&, const path_element&);
82
83namespace detail
84{
85
86/// What \c to_string of a \c path_element returns, out of line.
87JSONV_NODISCARD JSONV_PUBLIC std::string path_element_to_string(const path_element& elem);
88
89}
90
91/// The text \c operator<< writes for \a elem, which is how it appears in \c to_string of a \c path: <tt>[N]</tt> for an
92/// array index, and <tt>.key</tt> or a JSON string in brackets for an object key.
93///
94/// This is a template only so that a \c path_element is the one thing it takes. A \c path_element converts from numbers
95/// and strings, as a \c value does, so a plain function taking one made <tt>to_string(5)</tt> and
96/// <tt>to_string("x")</tt> ambiguous with <tt>to_string(const value&)</tt> wherever this header was included. They mean
97/// the \c value.
98template <std::same_as<path_element> T>
99JSONV_NODISCARD std::string to_string(const T& elem)
100{
101 return detail::path_element_to_string(elem);
102}
103
104/// Represents an exact path in some JSON structure.
106 public detail::generic_container<std::vector<path_element>>
107{
108public:
109 /// Creates a new, empty path.
111
112 /// Creates a path with the provided \a elements.
113 path(storage_type elements);
114
115 /// Create a \c path from a string definition. The syntax of this is ECMAScript's syntax for selecting elements, so
116 /// <tt>path::create(".foo.bar[1]")</tt> is equivalent to <tt>path({ "foo", "bar", 1 })</tt>.
117 ///
118 /// \throws std::invalid_argument if the \a specification is not valid, including an array index too large for a
119 /// \c std::size_t.
121 static path create(std::string_view specification);
122
123 path(const path&);
124 path& operator=(const path&);
125 path(path&&) noexcept;
126 path& operator=(path&&) noexcept;
127 ~path() noexcept;
128
129 /// Return a new path with the given \a subpath appended to the back.
131 path operator+(const path& subpath) const;
132 path& operator+=(const path& subpath);
133
134 /// Return a new path with the given \a elem appended to the back.
136 path operator+(path_element elem) const;
137 path& operator+=(path_element elem);
138};
139
140/// \{
141
142/// Write \a val in the syntax \c path::create reads. An object key which is an identifier (matching
143/// <tt>[a-zA-Z_$][a-zA-Z0-9_$]*</tt>) is written as <tt>.key</tt> and any other key as a JSON string in brackets, like
144/// <tt>["a b"]</tt>. Well-formed UTF-8 in a key is written as it is. An array index is written as <tt>[N]</tt> whatever
145/// the stream's locale, and the empty path as <tt>.</tt>.
146///
147/// So <tt>path::create(to_string(p)) == p</tt> for every path whose keys are well-formed UTF-8. A key which is not has
148/// each ill-formed byte written as a <tt>\\u00NN</tt> escape, and that reads back as the codepoint U+00NN rather than
149/// the byte.
150JSONV_PUBLIC std::ostream& operator<<(std::ostream&, const path& val);
151
152JSONV_NODISCARD JSONV_PUBLIC std::string to_string(const path& val);
153/// \}
154
155}
Represents an exact path in some JSON structure.
Definition path.hpp:107
path()
Creates a new, empty path.
path(storage_type elements)
Creates a path with the provided elements.
static path create(std::string_view specification)
Create a path from a string definition.
Copyright (c) 2014-2020 by Travis Gockel.
Copyright (c) 2014 by Travis Gockel.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
Definition config.hpp:132
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
Definition config.hpp:113
kind
Describes the kind of data a value holds.
Definition kind.hpp:30
JSONV_PUBLIC std::string to_string(const ast_node_type &type)
Get what operator<< writes for type as a std::string.
STL namespace.