@@ -11,74 +11,36 @@ import com.avsystem.commons.serialization._
1111
1212sealed trait RestStructure [T ] extends TypedMetadata [T ] {
1313 def schemaAdjusters : List [SchemaAdjuster ]
14+ def standaloneSchema : RestSchema [T ]
1415 def info : GenInfo [T ]
1516
1617 protected def applyAdjusters (schema : Schema ): Schema =
1718 schemaAdjusters.foldRight(schema)(_ adjustSchema _)
1819}
1920object RestStructure extends AdtMetadataCompanion [RestStructure ] {
20- implicit class LazyRestStructureOps [T ](restStructure : => RestStructure [T ]) {
21- def standaloneSchema : RestSchema [T ] = new RestSchema [T ] {
22- def createSchema (resolver : SchemaResolver ): RefOr [Schema ] = restStructure match {
23- case union : Union [T ] => union.createSchema(resolver)
24- case record : Record [T ] => record.createSchema(resolver, Opt .Empty )
25- case singleton : Singleton [T ] => singleton.createSchema(resolver, Opt .Empty )
26- }
27- def name : Opt [String ] = restStructure match {
28- case _ : Singleton [_] => Opt .Empty
29- case s => s.info.rawName.opt
30- }
31- }
32- }
33-
3421 @ positioned(positioned.here) case class Union [T ](
3522 @ multi @ reifyAnnot schemaAdjusters : List [SchemaAdjuster ],
3623 @ adtCaseMetadata @ multi cases : List [Case [_]],
3724 @ composite info : GenUnionInfo [T ]
3825 ) extends RestStructure [T ] {
3926
40- def createSchema (resolver : SchemaResolver ): RefOr [Schema ] = {
27+ def standaloneSchema : RestSchema [T ] =
28+ RestSchema .create(createSchema, info.rawName)
29+
30+ private def createSchema (resolver : SchemaResolver ): RefOr [Schema ] = {
4131 val caseFieldOpt = info.flatten.map(_.caseFieldName)
42- val caseSchemas = caseFieldOpt match {
43- case Opt (caseFieldName) => cases.map { cs =>
44- val caseName = cs.info.rawName
45- val caseRestSchema = cs match {
46- case record : Record [_] => RestSchema .create(record.createSchema(_, caseFieldOpt), caseName)
47- case singleton : Singleton [_] => RestSchema .create(singleton.createSchema(_, caseFieldOpt), caseName)
48- case custom : CustomCase [_] =>
49- val caseFieldSchema = RefOr (Schema .enumOf(List (caseName)))
50- custom.restSchema.map({
51- case RefOr .Value (caseSchema) => caseSchema.copy(
52- properties = caseSchema.properties + (caseFieldName -> caseFieldSchema),
53- required = caseFieldName :: caseSchema.required
54- )
55- case ref => Schema (allOf = List (RefOr (Schema (
56- `type` = DataType .Object ,
57- properties = Mapping (caseFieldName -> caseFieldSchema),
58- required = List (caseFieldName)
59- )), ref))
60- }, custom.taggedName)
61- }
62- resolver.resolve(caseRestSchema)
63- }
64- case Opt .Empty => cases.map { cs =>
65- val caseName = cs.info.rawName
66- val caseSchema = cs match {
67- case record : Record [_] => record.createSchema(resolver, Opt .Empty )
68- case singleton : Singleton [_] => singleton.createSchema(resolver, Opt .Empty )
69- case custom : CustomCase [_] => resolver.resolve(custom.restSchema)
70- }
71- RefOr (Schema (
72- `type` = DataType .Object ,
73- properties = Mapping (caseName -> caseSchema),
74- required = List (caseName)
75- ))
76- }
32+ val caseSchemas = cases.map { c =>
33+ val baseSchema = resolver.resolve(c.caseSchema(caseFieldOpt))
34+ if (caseFieldOpt.nonEmpty) baseSchema
35+ else RefOr (Schema (
36+ `type` = DataType .Object ,
37+ properties = Mapping (c.info.rawName -> baseSchema),
38+ required = List (c.info.rawName)
39+ ))
7740 }
7841 val disc = caseFieldOpt.map { caseFieldName =>
79- val mapping = Mapping (cases.collect {
80- case custom : CustomCase [_] if custom.taggedName != custom.info.rawName =>
81- (custom.info.rawName, custom.taggedName)
42+ val mapping = Mapping ((cases zip caseSchemas).collect {
43+ case (c, RefOr .Ref (ref)) => (c.info.rawName, ref)
8244 })
8345 Discriminator (caseFieldName, mapping)
8446 }
@@ -89,6 +51,7 @@ object RestStructure extends AdtMetadataCompanion[RestStructure] {
8951
9052 sealed trait Case [T ] extends TypedMetadata [T ] {
9153 def info : GenCaseInfo [T ]
54+ def caseSchema (caseFieldName : Opt [String ]): RestSchema [T ]
9255 }
9356 object Case extends AdtMetadataCompanion [Case ]
9457
@@ -99,9 +62,24 @@ object RestStructure extends AdtMetadataCompanion[RestStructure] {
9962 @ checked @ infer restSchema : RestSchema [T ],
10063 @ composite info : GenCaseInfo [T ]
10164 ) extends Case [T ] {
102- def taggedName : String =
103- if (restSchema.name.contains(info.rawName)) s " tagged ${info.rawName}"
104- else info.rawName
65+ def caseSchema (caseFieldName : Opt [String ]): RestSchema [T ] =
66+ caseFieldName.fold(restSchema) { cfn =>
67+ val caseFieldSchema = RefOr (Schema .enumOf(List (info.rawName)))
68+ val taggedName =
69+ if (restSchema.name.contains(info.rawName)) s " tagged ${info.rawName}"
70+ else info.rawName
71+ restSchema.map({
72+ case RefOr .Value (caseSchema) => caseSchema.copy(
73+ properties = caseSchema.properties + (cfn -> caseFieldSchema),
74+ required = cfn :: caseSchema.required
75+ )
76+ case ref => Schema (allOf = List (RefOr (Schema (
77+ `type` = DataType .Object ,
78+ properties = Mapping (cfn -> caseFieldSchema),
79+ required = List (cfn)
80+ )), ref))
81+ }, taggedName)
82+ }
10583 }
10684
10785 /**
@@ -113,7 +91,13 @@ object RestStructure extends AdtMetadataCompanion[RestStructure] {
11391 @ composite info : GenCaseInfo [T ]
11492 ) extends RestStructure [T ] with Case [T ] {
11593
116- def createSchema (resolver : SchemaResolver , caseFieldName : Opt [String ]): RefOr [Schema ] =
94+ def standaloneSchema : RestSchema [T ] =
95+ RestSchema .create(createSchema(_, Opt .Empty ), info.rawName)
96+
97+ def caseSchema (caseFieldName : Opt [String ]): RestSchema [T ] =
98+ RestSchema .create(createSchema(_, caseFieldName), caseFieldName.map(_ => info.rawName).toOptArg)
99+
100+ private def createSchema (resolver : SchemaResolver , caseFieldName : Opt [String ]): RefOr [Schema ] =
117101 (fields, caseFieldName) match {
118102 case (single :: Nil , Opt .Empty ) if info.transparent =>
119103 SchemaAdjuster .adjustRef(schemaAdjusters, resolver.resolve(single.restSchema))
@@ -139,6 +123,12 @@ object RestStructure extends AdtMetadataCompanion[RestStructure] {
139123 @ composite info : GenCaseInfo [T ]
140124 ) extends RestStructure [T ] with Case [T ] {
141125
126+ def standaloneSchema : RestSchema [T ] =
127+ RestSchema .create(createSchema(_, Opt .Empty ))
128+
129+ def caseSchema (caseFieldName : Opt [String ]): RestSchema [T ] =
130+ RestSchema .create(createSchema(_, caseFieldName), caseFieldName.map(_ => info.rawName).toOptArg)
131+
142132 def createSchema (resolver : SchemaResolver , caseFieldName : Opt [String ]): RefOr [Schema ] =
143133 RefOr (applyAdjusters(Schema (`type` = DataType .Object ,
144134 properties = Mapping (caseFieldName.map(cfn => (cfn, RefOr (Schema .enumOf(List (info.rawName))))).toList),
0 commit comments