Skip to content

Commit 639bd73

Browse files
authored
Merge pull request #17 from gregsdennis/pointer/low-alloc
update schema docs
2 parents 97e43a8 + de98a5a commit 639bd73

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

_docs/pointer/basics.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,55 @@ var success = pointer.TryEvaluate(element, out var result);
8787
> The designers of the `JsonNode` API have elected (for [reasons](https://github.com/dotnet/designs/blob/40794be63ecd8b35e9596412050a84dedd575b99/accepted/2020/serializer/WriteableDomAndDynamic.md#missing-vs-null) I [disagree](https://github.com/dotnet/runtime/issues/66948#issuecomment-1080148457) with) to consider JSON null and .Net null to be equivalent. This goes against both my personal experience building Manatee.Json and the `JsonElement` API, both of which maintain a separation between these two null concepts. Because of the unified design, it's impossible to determine whether a returned `JsonNode` value of `null` represents a value that is present but null or it is merely absent from the data. To accommodate this, the evaluation method can only support the familiar `TryParse()` signature. A return of `true` indicates the value was found, and `false` indicates it was not. In the case of a `true` return, `result` may still be null, indicating the value was found and was a JSON null.
8888
{: .prompt-info }
8989

90+
### Pointer math
91+
92+
You can also combine and augment pointers in different ways.
93+
94+
Joining two pointers together:
95+
96+
```c#
97+
var pointer1 = JsonPointer.Parse("/objects/and");
98+
var pointer2 = JsonPointer.Parse("/3/arrays");
99+
var final = pointer1.Combine(pointer2);
100+
```
101+
102+
Appending additional segments to an existing pointer:
103+
104+
```c#
105+
var pointer = JsonPointer.Parse("/objects/and");
106+
var final = pointer1.Combine(3, "arrays");
107+
```
108+
109+
### Access pointer parts and create sub-pointers
110+
111+
You can retrieve the individual segments using the indexer:
112+
113+
```c#
114+
var pointer = JsonPointer.Parse("/objects/and/3/arrays");
115+
var andSegment = pointer[1]; // "and" (string)
116+
```
117+
118+
If you're using .Net 8 or higher, the indexer also supports `Range` values, so you can obtain a new pointer containing a portion of the segments.
119+
120+
Get the immediate parent:
121+
122+
```c#
123+
var pointer = JsonPointer.Parse("/objects/and/3/arrays");
124+
var parent = pointer[..^1]; // /objects/and/3
125+
```
126+
127+
Or get the local pointer (imagine you've navigated to `/objects/and/` and you need the pointer relative to where you are):
128+
129+
```c#
130+
var pointer = JsonPointer.Parse("/objects/and/3/arrays");
131+
var local = pointer[^2..]; // /3/arrays
132+
```
133+
134+
There are also method versions of this functionality, which are also available if you're not yet using .Net 8: `.GetAncestor(int)` and `.GetLocal()`.
135+
136+
> Accessing pointers acts like accessing strings: getting segments has no allocations (like getting a `char` via the string's `int` indexer), but creating a sub-pointer _does_ allocate a new `JsonPointer` instance (like creating a substring via the string's `Range` indexer).
137+
{: .prompt-info }
138+
90139
### Building pointers using Linq expressions {#linq}
91140

92141
When building a pointer using the `Create<T>()` method which takes a Linq expression, there are a couple of things to be aware of.

_docs/schema/basics.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ There are two options when building a schema: defining it inline using the fluen
4747

4848
## Serialization and Deserialization {#schema-deserialization}
4949

50-
*JsonSchema.Net* schemas are fully serializable.
50+
_JsonSchema.Net_ schemas are fully serializable.
5151

5252
```c#
5353
var mySchema = JsonSchema.FromText(content);
@@ -463,7 +463,8 @@ New formats must be registered via the `Formats.Register()` static method. This
463463

464464
The `EvaluationOptions` class gives you a few configuration points for customizing how the evaluation process behaves. It is an instance class and can be passed into the `JsonSchema.Evaluate()` method. If no options are explicitly passed, a copy of `JsonSchemaOptions.Default` will be used.
465465

466-
- `EvaluateAs` - Indicates which schema version to process as. This will filter the keywords of a schema based on their support. This means that if any keyword is not supported by this version, it will be ignored.
466+
- `EvaluateAs` - Indicates which schema version to process as. This will filter the keywords of a schema based on their support. This means that if any keyword is not supported by this version, it will be ignored. This will need to be set when you create the options.
467+
- `SchemaRegistry` - Provides a way to register schemas only for the evaluations that use this set of options.
467468
- `EvaluateMetaSchema` - Indicates whether the schema should be evaluated against its `$schema` value (its meta-schema). This is not typically necessary. Note that the evaluation process will still attempt to resolve the meta-schema. \*
468469
- `OutputFormat` - You already read about output formats above. This is the property that controls it all. By default, a single "flag" node is returned. This also yields the fastest evaluation times as it enables certain optimizations.
469470
- `RequireFormatValidation` - Forces `format` validation.
@@ -549,7 +550,7 @@ var randomString = JsonSchema.FromFile("random-string.json");
549550
SchemaRegistry.Global.Register(new Uri("http://localhost/random-string"), randomString);
550551
```
551552

552-
Now *JsonSchema.Net* will be able to resolve the reference.
553+
Now _JsonSchema.Net_ will be able to resolve the reference.
553554

554555
> `JsonSchema.FromFile()` automatically sets the schema's base URI to the file path. If you intend to use file paths in your references (e.g. `file:///C:\random-string.json`), then just register the schema without passing a URI:
555556
>
@@ -576,7 +577,7 @@ var referenceableJson = new JsonNodeBaseDocument(json, "http://localhost/jsondat
576577
SchemaRegistry.Global.Register(referenceableJson);
577578
578579
var schema = new JsonSchemaBuilder()
579-
.Ref("http://localhost/jsondata#/schema)
580+
.Ref("http://localhost/jsondata#/schema")
580581
.Build();
581582
```
582583

_docs/schema/vocabs.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ The `maximum` keyword is basically all instance. It asks, "Is the instance a nu
158158

159159
```c#
160160
public KeywordConstraint GetConstraint(SchemaConstraint schemaConstraint,
161-
IReadOnlyList<KeywordConstraint> localConstraints,
161+
ReadOnlySpan<KeywordConstraint> localConstraints,
162162
EvaluationContext context)
163163
{
164164
return new KeywordConstraint(Name, Evaluator);
@@ -218,7 +218,7 @@ More specifically to our task here, `properties` gives us a list of subschemas t
218218

219219
```c#
220220
public KeywordConstraint GetConstraint(SchemaConstraint schemaConstraint,
221-
IReadOnlyList<KeywordConstraint> localConstraints,
221+
ReadOnlySpan<KeywordConstraint> localConstraints,
222222
EvaluationContext context)
223223
{
224224
var subschemaConstraints = Properties

0 commit comments

Comments
 (0)