Repository: GREsau/schemars
Pull request #44 (2020-07-30 18:44:27)

Add support to enforce inlining of all subschemas instead of using references
This PR adds a new flag to `SchemaSettings` which avoids references and enforces inlining of all subschemas. This is needed to support use cases like `openAPIV3Schema` in [Kubernetes CustomResourceDefinitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions). The JSON schemas as used by Kubernetes `CustomResourceDefinition`s  are [constrained](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) and besides others must not contain `definitions` or `$ref`.


Patch:
diff --git a/schemars/src/gen.rs b/schemars/src/gen.rs
index de35268..5ef54b5 100644
--- a/schemars/src/gen.rs
+++ b/schemars/src/gen.rs
@@ -39,6 +39,10 @@ pub struct SchemaSettings {
     pub meta_schema: Option<String>,
     /// A list of visitors that get applied to all generated root schemas.
     pub visitors: Vec<Box<dyn GenVisitor>>,
+    /// Inline all subschemas instead of using references.
+    ///
+    /// Defaults to `false`.
+    pub inline_subschemas: bool,
     _hidden: (),
 }
 
@@ -57,6 +61,7 @@ impl SchemaSettings {
             definitions_path: "#/definitions/".to_owned(),
             meta_schema: Some("http://json-schema.org/draft-07/schema#".to_owned()),
             visitors: vec![Box::new(RemoveRefSiblings)],
+            inline_subschemas: false,
             _hidden: (),
         }
     }
@@ -69,6 +74,7 @@ impl SchemaSettings {
             definitions_path: "#/definitions/".to_owned(),
             meta_schema: Some("https://json-schema.org/draft/2019-09/schema".to_owned()),
             visitors: Vec::default(),
+            inline_subschemas: false,
             _hidden: (),
         }
     }
@@ -92,6 +98,7 @@ impl SchemaSettings {
                     retain_examples: false,
                 }),
             ],
+            inline_subschemas: false,
             _hidden: (),
         }
     }
@@ -196,7 +203,7 @@ impl SchemaGenerator {
     /// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) schemas, then this method will
     /// add them to the `SchemaGenerator`'s schema definitions.
     pub fn subschema_for<T: ?Sized + JsonSchema>(&mut self) -> Schema {
-        if !T::is_referenceable() {
+        if !T::is_referenceable() || self.settings.inline_subschemas {
             return T::json_schema(self);
         }
 


Test patch:
diff --git a/schemars/tests/expected/inline-subschemas.json b/schemars/tests/expected/inline-subschemas.json
new file mode 100644
index 0000000..0571675
--- /dev/null
+++ b/schemars/tests/expected/inline-subschemas.json
@@ -0,0 +1,23 @@
+{
+  "$schema":  "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
+  "properties": {
+    "spec": {
+      "properties": {
+        "replicas": {
+          "format": "uint32",
+          "minimum": 0,
+          "type": "integer"
+        }
+      },
+      "required": [
+        "replicas"
+      ],
+      "type": "object"
+    }
+  },
+  "required": [
+     "spec"
+  ],
+  "title": "MyJob",
+  "type": "object"
+}
\ No newline at end of file
diff --git a/schemars/tests/inline_subschemas.rs b/schemars/tests/inline_subschemas.rs
new file mode 100644
index 0000000..62bc7cc
--- /dev/null
+++ b/schemars/tests/inline_subschemas.rs
@@ -0,0 +1,21 @@
+mod util;
+use schemars::gen::SchemaSettings;
+use schemars::JsonSchema;
+use util::*;
+
+#[derive(Debug, JsonSchema)]
+pub struct MyJob {
+    pub spec: MyJobSpec,
+}
+
+#[derive(Debug, JsonSchema)]
+pub struct MyJobSpec {
+    pub replicas: u32,
+}
+
+#[test]
+fn struct_normal() -> TestResult {
+    let mut settings = SchemaSettings::openapi3();
+    settings.inline_subschemas = true;
+    test_generated_schema::<MyJob>("inline-subschemas", settings)
+}