amazon-ion / ion-schema-rust

Rust implementation of Ion Schema
https://amazon-ion.github.io/ion-schema/sandbox
Apache License 2.0
13 stars 6 forks source link

adds `IonPath` implementation for `Violation` #148

Closed desaikd closed 1 year ago

desaikd commented 1 year ago

Issue #140:

Description of changes:

This PR works on adding changes to add path information for an Ion value that was invalid and resulted into violation.

List of changes:

Example

Schema

type::{
  name: customer,
  type: struct,
  fields: {
    addresses: {
      type: list,
      element: {
        type: struct,
        fields: {
          city: { type: string, codepoint_length: range::[8, max] },
          state: symbol
        }
      }
    }
  }
}

Ion Value to be validated:

{
  addresses: [
    { city: "Seattle", state: WA },
    { city: "Portland", state: OR },
    { city: "San Francisco", state: CA }
  ]
}

Output Violation (Using the deeply nested violation for example here):

Violation {
    constraint: "{type: string, codepoint_length: range::[8, max]}",
    code: TypeConstraintsUnsatisfied,
    message: "value didn't satisfy type constraint(s)",
    ion_path: (addresses 0 city),
    violations: [
        Violation {
            constraint: "codepoint_length",
            code: InvalidLength,
            message: "expected codepoint length range::[ 8, max ] found 7",
            ion_path: (addresses 0 city),
            violations: [],
        },
    ],
}

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

desaikd commented 1 year ago

We can leverage Ion to do the heavy lifting for us here by making the ion_path a list or sexp. (I'm going to use a sexp for my examples, but a list would also work.) Here are some examples:

// Violation at the "root"
()

// Violation at the field "com.amazon.foo" in the second value of a document
// Using current syntax: ./[2].com.amazon.foo
(2 'com.amazon.foo')

// Violation at the field "foo" in the field "amazon" in the field "com" in the second value of a document
// Using current syntax: ./[2].com.amazon.foo
(2 com amazon foo)

// Violation at ./addresses[0].city
(addresses 0 city)

// Violation at the [0] field when validating a top level struct.
('[0]')

What do you think?

Are you suggesting something similar to https://github.com/amazon-ion/ion-java-path-extraction#search-paths. I think that sounds good to me. That way there will not be any ambiguity with the path representation.

popematt commented 1 year ago

Are you suggesting something similar to https://github.com/amazon-ion/ion-java-path-extraction#search-paths. I think that sounds good to me. That way there will not be any ambiguity with the path representation.

There is some similarity, but I would avoid explicitly tying it to the Ion Path Extractor because Ion Path Extractor treats each top-level value in a stream as a separate thing to match against, whereas Ion Schema needs some way to indicate "the whole stream/document" or "the Nth element of the stream/document". In other words, Ion Path Extractor treats every top-level value as a separate root for matching, but Ion Schema treats a value or a stream of values as a single root for validation.

desaikd commented 1 year ago

New representation of IonPath according to suggested changes is as following:

Violation {
    constraint: "{type: string, codepoint_length: range::[8, max]}",
    code: TypeConstraintsUnsatisfied,
    message: "value didn't satisfy type constraint(s)",
    ion_path: (addresses 0 city),
    violations: [
        Violation {
            constraint: "codepoint_length",
            code: InvalidLength,
            message: "expected codepoint length range::[ 8, max ] found 7",
            ion_path: (addresses 0 city),
            violations: [],
        },
    ],
}