HCursor abstract
abstract class HCursor extends ACursorA successful ACursor positioned at a Json value.
HCursor is the working cursor type for navigation and modification. Concrete subtypes are TopCursor (root), ArrayCursor (inside an array), and ObjectCursor (inside an object).
Inheritance
Object → ACursor → HCursor
Constructors
HCursor() const
Implementation
const HCursor(super.lastCursor, super.lastOp);Properties
failed no setter inherited
bool get failedReturns true if the cursor is in a failed state.
Inherited from ACursor.
Implementation
bool get failed => !succeeded;hashCode no setter inherited
int get hashCodeThe hash code for this object.
A hash code is a single integer which represents the state of the object that affects operator == comparisons.
All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).
If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.
Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.
Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.
If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.
Inherited from Object.
Implementation
external int get hashCode;index no setter inherited
Option<int> get indexIf the cursor is inside a JArray, returns Some with the current index.
Inherited from ACursor.
Implementation
Option<int> get index => none();key no setter inherited
Option<String> get keyIf the cursor is inside a JObject, returns Some with the current key.
Inherited from ACursor.
Implementation
Option<String> get key => none();keys no setter override
If the focus is a JObject, returns Some with its keys.
Implementation
@override
Option<IList<String>> get keys =>
Option.when(() => value is JObject, () => (value as JObject).value.keys);lastCursor final inherited
final HCursor? lastCursorThe cursor that was active before the last operation, or null at the root.
Inherited from ACursor.
Implementation
final HCursor? lastCursor;lastOp final inherited
final CursorOp? lastOpThe operation that produced this cursor from lastCursor, or null at the root.
Inherited from ACursor.
Implementation
final CursorOp? lastOp;pathString no setter inherited
String get pathStringA dot/bracket string representing the current cursor position (e.g. .user.address[0]).
Inherited from ACursor.
Implementation
String get pathString => PathToRoot.toPathString(pathToRoot());runtimeType no setter inherited
Type get runtimeTypeA representation of the runtime type of the object.
Inherited from Object.
Implementation
external Type get runtimeType;succeeded no setter override
bool get succeededReturns true if the cursor is in a successful state.
Implementation
@override
bool get succeeded => true;value no setter
Json get valueThe Json value currently in focus.
Implementation
Json get value;values no setter override
If the focus is a JArray, returns Some with its elements.
Implementation
@override
Option<IList<Json>> get values =>
Option.when(() => value is JArray, () => (value as JArray).value);Methods
addOp()
Returns a new cursor with the same focus but with cursor/op appended to the history.
Implementation
HCursor addOp(HCursor cursor, CursorOp op);decode() inherited
DecodeResult<DecodingFailure, A> decode<A>(Decoder<A> decoder)Decodes the focused value using decoder.
Inherited from ACursor.
Implementation
DecodeResult<A> decode<A>(Decoder<A> decoder) => decoder.tryDecodeC(this);delete() inherited
ACursor delete()Delete the focus and move to the parent.
Inherited from ACursor.
Implementation
ACursor delete();downArray() override
ACursor downArray()If the focus is a JSON array, move to the first element.
Implementation
@override
ACursor downArray() {
final self = value;
if (self is JArray && self.value.nonEmpty) {
return ArrayCursor(self.value, 0, this, false, this, CursorOp.downArray);
} else {
return fail(CursorOp.downArray);
}
}downField() override
ACursor downField(String key)If the focus is a JSON object, move to the value at the given key.
Implementation
@override
ACursor downField(String key) {
final self = value;
final op = CursorOp.downField(key);
if (self is JObject) {
return self.value.contains(key)
? ObjectCursor(self.value, key, this, false, this, op)
: fail(op);
} else {
return fail(op);
}
}downN() override
ACursor downN(int n)If the focus is a JSON array, move to element at the given index.
Implementation
@override
ACursor downN(int n) {
final self = value;
if (self is JArray && 0 <= n && n < self.value.size) {
return ArrayCursor(self.value, n, this, false, this, CursorOp.downN(n));
} else {
return fail(CursorOp.downN(n));
}
}fail()
Returns a FailedCursor recording that op failed from this cursor.
Implementation
ACursor fail(CursorOp op) => FailedCursor(this, op);field() inherited
ACursor field(String key)If the focus is a JSON object, move to the sibling at the given key.
Inherited from ACursor.
Implementation
ACursor field(String key);find()
Moves right through array siblings until p returns true for the focused value, or returns a FailedCursor if no element matches.
Implementation
ACursor find(Function1<Json, bool> p) {
var current = this as ACursor;
while (current is HCursor) {
if (p(current.value)) return current;
current = current.right();
}
return current;
}focus() override
Returns Some with the focused Json if the cursor succeeded, or None if it failed.
Implementation
@override
Option<Json> focus() => Some(value);get() inherited
DecodeResult<DecodingFailure, A> get<A>(String key, Decoder<A> decoder)Navigates to key and decodes the value using decoder.
Inherited from ACursor.
Implementation
DecodeResult<A> get<A>(String key, Decoder<A> decoder) => downField(key).decode(decoder);getOrElse() inherited
DecodeResult<DecodingFailure, A> getOrElse<A>(
String key,
Decoder<A> decoder,
A Function() fallback,
)Navigates to key and decodes the value; returns fallback if the field is absent or decoding yields None.
Inherited from ACursor.
Implementation
DecodeResult<A> getOrElse<A>(String key, Decoder<A> decoder, Function0<A> fallback) =>
get(key, decoder.optional()).fold(
(err) => fallback().asRight(),
(aOpt) => aOpt.fold(() => fallback().asRight(), (a) => a.asRight()),
);history() inherited
Returns the list of CursorOps that led to this cursor, most-recent first. Used to reconstruct a path for DecodingFailure messages.
Inherited from ACursor.
Implementation
IList<CursorOp> history() {
final ops = <CursorOp>[];
var current = this as ACursor?;
while (current != null && current.lastOp != null) {
ops.add(current.lastOp!);
current = current.lastCursor;
}
return ilist(ops);
}left() inherited
ACursor left()If the focus is an element in a JSON array, move to the left.
Inherited from ACursor.
Implementation
ACursor left();noSuchMethod() inherited
dynamic noSuchMethod(Invocation invocation)Invoked when a nonexistent method or property is accessed.
A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:
dynamic object = 1;
object.add(42); // Statically allowed, run-time errorThis invalid code will invoke the noSuchMethod method of the integer 1 with an Invocation representing the .add(42) call and arguments (which then throws).
Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.
A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:
class MockList<T> implements List<T> {
noSuchMethod(Invocation invocation) {
log(invocation);
super.noSuchMethod(invocation); // Will throw.
}
}
void main() {
MockList().add(42);
}This code has no compile-time warnings or errors even though the MockList class has no concrete implementation of any of the List interface methods. Calls to List methods are forwarded to noSuchMethod, so this code will log an invocation similar to Invocation.method(#add, [42]) and then throw.
If a value is returned from noSuchMethod, it becomes the result of the original invocation. If the value is not of a type that can be returned by the original invocation, a type error occurs at the invocation.
The default behavior is to throw a NoSuchMethodError.
Inherited from Object.
Implementation
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);pathToRoot() inherited
PathToRoot pathToRoot()Reconstructs the full PathToRoot from the cursor chain.
Inherited from ACursor.
Implementation
PathToRoot pathToRoot() {
// TODO: Revisit lastCursorParentOrLastCursor
var currentCursor = this as ACursor?;
var acc = PathToRoot.empty;
while (currentCursor != null) {
if (currentCursor.failed) {
// If the cursor is in a failed state, we lose context on what the
// attempted last position was. Since we usually want to know this
// for error reporting, we use the lastOp to attempt to recover that
// state. We only care about operations which imply a path to the
// root, such as a field selection.
final lastCursor = currentCursor.lastCursor;
final lastOp = currentCursor.lastOp;
switch (lastOp) {
case Field _:
currentCursor = currentCursor.lastCursor;
acc = acc.prependElem(PathElem.objectKey(lastOp.key));
case DownField _:
// We tried to move down, and then that failed, so the field was missing.
currentCursor = currentCursor.lastCursor;
acc = acc.prependElem(PathElem.objectKey(lastOp.key));
case DownArray _:
// We tried to move into an array, but it must have been empty.
currentCursor = currentCursor.lastCursor;
acc = acc.prependElem(PathElem.arrayIndex(0));
case DownN _:
// We tried to move into an array at index N, but there was no element there.
currentCursor = currentCursor.lastCursor;
acc = acc.prependElem(PathElem.arrayIndex(lastOp.n));
case MoveLeft _:
// We tried to move to before the start of the array.
currentCursor = currentCursor.lastCursor;
acc = acc.prependElem(PathElem.arrayIndex(-1));
case MoveRight _:
if (lastCursor is ArrayCursor) {
// We tried to move to past the end of the array.
currentCursor = lastCursor.parent;
acc = acc.prependElem(PathElem.arrayIndex(lastCursor.indexValue + 1));
} else {
// Invalid state, skip for now.
currentCursor = currentCursor.lastCursor;
}
default:
// CursorOp.MoveUp or CursorOp.DeleteGoParent, both are move up
// events.
//
// Recalling we are in a failed branch here, this should only
// fail if we are already at the top of the tree or if the
// cursor state is broken, in either
// case this is the only valid action to take.
currentCursor = currentCursor.lastCursor;
}
} else {
switch (currentCursor) {
case ArrayCursor _:
final cursor = currentCursor;
currentCursor = cursor.parent;
acc = acc.prependElem(PathElem.arrayIndex(cursor.indexValue));
case ObjectCursor _:
final cursor = currentCursor;
currentCursor = cursor.parent;
acc = acc.prependElem(PathElem.objectKey(cursor.keyValue));
case TopCursor _:
currentCursor = null; // Exit loop
default:
currentCursor = currentCursor.lastCursor;
}
}
}
return acc;
}replace()
Returns a new cursor with the focus replaced by newValue, recording cursor as the previous cursor and op as the operation.
Implementation
HCursor replace(Json newValue, HCursor cursor, CursorOp? op);right() inherited
ACursor right()If the focus is an element in a JSON array, move to the right.
Inherited from ACursor.
Implementation
ACursor right();root() override
HCursor root()Returns the root HCursor of the cursor chain, or null if unavailable.
Implementation
@override
HCursor root() => this is TopCursor ? this : (up() as HCursor).root();set() inherited
Returns a new cursor with the focus replaced by j.
Inherited from ACursor.
Implementation
ACursor set(Json j) => withFocus((_) => j);success() override
Returns Some with this cursor if it succeeded, or None if it failed.
Implementation
@override
Option<HCursor> success() => Some(this);top() override
Returns Some with the root Json value if the cursor succeeded.
Implementation
@override
Option<Json> top() => Some(root().value);toString() override
String toString()A string representation of this object.
Some classes have a default textual representation, often paired with a static parse function (like int.parse). These classes will provide the textual representation as their string representation.
Other classes have no meaningful textual representation that a program will care about. Such classes will typically override toString to provide useful information when inspecting the object, mainly for debugging or logging.
Implementation
@override
String toString() => 'HCursor($lastCursor, $lastOp, $value)';up() inherited
ACursor up()Move focus to the parent.
Inherited from ACursor.
Implementation
ACursor up();withFocus() override
Returns a new cursor with the focused Json replaced by f(focused).
Implementation
@override
HCursor withFocus(Function1<Json, Json> f) => replace(f(value), this, null);Operators
operator ==() inherited
bool operator ==(Object other)The equality operator.
The default behavior for all Objects is to return true if and only if this object and other are the same object.
Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:
Total: It must return a boolean for all arguments. It should never throw.
Reflexive: For all objects
o,o == omust be true.Symmetric: For all objects
o1ando2,o1 == o2ando2 == o1must either both be true, or both be false.Transitive: For all objects
o1,o2, ando3, ifo1 == o2ando2 == o3are true, theno1 == o3must be true.
The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.
If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.
Inherited from Object.
Implementation
external bool operator ==(Object other);Static Methods
fromJson()
Creates an HCursor positioned at the root of json.
Implementation
static HCursor fromJson(Json json) => TopCursor(json, null, null);