yaml-language-server icon indicating copy to clipboard operation
yaml-language-server copied to clipboard

Enable loading of customTags from inside the JSON schemas themselves

Open ssbarnea opened this issue 4 years ago • 4 comments

JSON schemas can contain addition information that is not part of the schema itself, this means that they can also expose which customTags are expected to be found on a specific document.

This could be of great use because each schema published is the likely person known which tags their projects support. It would also mean that we avoid avoid the need to force users to add all kind of customTags to their user settings.json. Also adding global such customTags is not the best practice because it would prevent us from detecting if a tag unsupported by one product/file-type is added.

I propose looking for something like:

{
    "$schema": "https://json-schema.org/draft/2019-09/schema",
    "properties": {
        "customTags": ["!encrypted/pkcs1-oaep sequence"]
    },

I verified and that schema is passing validation.

ssbarnea avatar Jan 18 '20 17:01 ssbarnea

I like the idea. It fits with our latest changes that makes schema extensions the source of additional features.

gorkem avatar Jan 19 '20 16:01 gorkem

Would it maybe possible to allow such a tag reference any validation e.g. something like

{
  "anyOf": [
    { "type": "string", "maxLength": 5 },
    { "type": "number", "minimum": 0 }
  ]
}

ModProg avatar Dec 22 '22 13:12 ModProg

Would there be a way to specify where these tags would be allowed inside a schema?

ModProg avatar Dec 22 '22 13:12 ModProg

To elaborate why I'm asking for this, my uscase is the serde_yaml crate for rust, that uses tags to specify enum variants: https://github.com/dtolnay/serde-yaml

Enums serialize using YAML's !tag syntax to identify the variant name.
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Enum {
    Unit,
    Newtype(usize),
    Tuple(usize, usize, usize),
    Struct { x: f64, y: f64 },
}

fn main() -> Result<(), serde_yaml::Error> {
    let yaml = "
        - !Newtype 1
        - !Tuple [0, 0, 0]
        - !Struct {x: 1.0, y: 2.0}
    ";
    let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Newtype(1));
    assert_eq!(values[1], Enum::Tuple(0, 0, 0));
    assert_eq!(values[2], Enum::Struct { x: 1.0, y: 2.0 });

    // The last two in YAML's block style instead:
    let yaml = "
        - !Tuple
          - 0
          - 0
          - 0
        - !Struct
          x: 1.0
          y: 2.0
    ";
    let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Tuple(0, 0, 0));
    assert_eq!(values[1], Enum::Struct { x: 1.0, y: 2.0 });

    // Variants with no data can be written using !Tag or just the string name.
    let yaml = "
        - Unit  # serialization produces this one
        - !Unit
    ";
    let values: Vec<Enum> = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Unit);
    assert_eq!(values[1], Enum::Unit);

    Ok(())
}

ModProg avatar Dec 22 '22 13:12 ModProg