Skip to content

Support merging types with multiple regex validations (allOf).#1008

Merged
inickles merged 3 commits into
mainfrom
inickles/merge
May 15, 2026
Merged

Support merging types with multiple regex validations (allOf).#1008
inickles merged 3 commits into
mainfrom
inickles/merge

Conversation

@inickles
Copy link
Copy Markdown
Contributor

@inickles inickles commented May 1, 2026

I tried running Typify on a schema that had an allOf declaration:

    "EmailAddressDatatype": {
      "description": "An email address string formatted according to RFC 6531.",
      "allOf": [
        {
          "$ref": "#/definitions/StringDatatype"
        },
        {
          "type": "string",
          "format": "email",
          "pattern": "^.+@.+$"
        }
      ]
    },

but this resulted in an error: Message: not implemented: merging distinct patterns is impractical

This PR handles the case of multiple regex validation patterns by chaining them with lookaheads.

Consider the test code in this PR at typify-impl/tests/all_of.json:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "TriplePattern": {
            "allOf": [
                {
                    "type": "string",
                    "pattern": "^[a-z].+$",
                    "format": "custom-id"
                },
                { "type": "string", "pattern": "^.{4,8}$" },
                { "type": "string", "pattern": ".+[a-z]$" }
            ]
        }
    }
}

Regex validation for this will now result in:

::regress::Regex::new("(?=^[a-z].+$)(?=^.{4,8}$)(?=.+[a-z]$)")

This adds a new test all_of in typify-test/src/main.rs that verifies this functionality works as expected. It uses that all_of.json, which is also used for an integration test in testify-impl.

Fun fact, the original schema I was trying to process was the NIST OSCAL schema at https://github.com/usnistgov/OSCAL/releases/download/v1.2.2/oscal_catalog_schema.json. I am able to successfully run Typify on that schema with this PR. The pattern for that EmailAddressDatatype type results in:

::regress::Regex::new("(?=^\\S(.*\\S)?$)(?=^.+@.+$)")

@inickles inickles requested a review from ahl May 1, 2026 16:18
Copy link
Copy Markdown
Collaborator

@ahl ahl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@inickles I made some edits; please review?

Some(unhandled) => {
info!("treating a string format '{}' as a String", unhandled);
Ok((TypeEntryDetails::String.into(), metadata))
// Apply constaints when there is no format or the format isn't
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simplified this rather than duplicating the code.

Comment thread typify-test/build.rs
NonAsciiChars::add(&mut type_space);
UnknownFormat::add(&mut type_space);
ipnetwork::IpNetwork::add(&mut type_space);
TriplePattern::add(&mut type_space);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used a more consistent pattern here.

@inickles
Copy link
Copy Markdown
Contributor Author

@inickles I made some edits; please review?

those changes lgtm, thanks!

@inickles inickles merged commit bbfad31 into main May 15, 2026
4 checks passed
@inickles inickles deleted the inickles/merge branch May 15, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants