| 253 | |
| 254 | template <typename Jsonlike> |
| 255 | JsonOp<Jsonlike> genericObjectArrayOp(String path, EmptyPathOp<Jsonlike> emptyPathOp, ObjectOp<Jsonlike> objectOp, ArrayOp<Jsonlike> arrayOp) { |
| 256 | return [=](Jsonlike const& parent, Maybe<String> const& key) -> Jsonlike { |
| 257 | if (key.isNothing()) |
| 258 | return emptyPathOp(parent); |
| 259 | if (parent.type() == Json::Type::Array) { |
| 260 | if (*key == "-") |
| 261 | return arrayOp(parent, {}); |
| 262 | Maybe<size_t> i = maybeLexicalCast<size_t>(*key); |
| 263 | if (!i) |
| 264 | throw TraversalException::format("Cannot parse '{}' as index in Json path \"{}\"", *key, path); |
| 265 | if (i && *i > parent.size()) |
| 266 | throw TraversalException::format("Index {} out of range in Json path \"{}\"", *key, path); |
| 267 | if (i && *i == parent.size()) |
| 268 | i = {}; |
| 269 | return arrayOp(parent, i); |
| 270 | } else if (parent.type() == Json::Type::Object) { |
| 271 | return objectOp(parent, *key); |
| 272 | } else { |
| 273 | throw TraversalException::format("Tried to set key '{}' in non-object type in pathSet(\"{}\")", *key, path); |
| 274 | } |
| 275 | }; |
| 276 | } |
| 277 | |
| 278 | template <typename Jsonlike> |
| 279 | Jsonlike pathSet(Jsonlike const& base, PathParser parser, String const& path, Jsonlike const& value) { |