Skip to content

Commit 37223ee

Browse files
committed
Continue with fixes
1 parent 8492b14 commit 37223ee

File tree

6 files changed

+245
-206
lines changed

6 files changed

+245
-206
lines changed

packages/sury/src/Sury.res

Lines changed: 109 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,7 @@ let setHas = (has, tag: tag) => {
19391939
let jsonName = `JSON`
19401940

19411941
let jsonString = shaken("jsonString")
1942+
let json = shaken("json")
19421943

19431944
module Literal = {
19441945
let literalDecoder = Builder.make((b, ~input, ~selfSchema, ~path) => {
@@ -2064,10 +2065,6 @@ let rec parse = (prevB: b, ~schema, ~input as inputArg: val, ~path, ~reuseScope=
20642065
| Some(to) =>
20652066
switch schema {
20662067
| {parser} => input := parser(b, ~input=input.contents, ~selfSchema=schema, ~path)
2067-
// FIXME: Run encoder on the input.schema instead of the schema
2068-
// eg for the case when jsonString returns an input with JSON schema
2069-
// | {encoder} if input.contents.schema === schema =>
2070-
// input := encoder(b, ~input=input.contents, ~selfSchema=schema, ~path)
20712068
| _ => ()
20722069
}
20732070

@@ -2091,7 +2088,7 @@ and isAsyncInternal = (schema, ~defs) => {
20912088
var: B._var,
20922089
flag: ValFlag.none,
20932090
inline: Builder.intitialInputVar,
2094-
schema: unknown, // FIXME:
2091+
schema: unknown,
20952092
}
20962093
let output = parse(b, ~schema, ~input, ~path=Path.empty)
20972094
let isAsync = output.flag->Flag.has(ValFlag.async)
@@ -2107,30 +2104,10 @@ and isAsyncInternal = (schema, ~defs) => {
21072104
and internalCompile = (~schema, ~flag, ~defs) => {
21082105
let b = B.rootScope(~flag, ~defs)
21092106

2110-
if flag->Flag.unsafeHas(Flag.jsonableOutput) {
2111-
let output = schema->reverse
2112-
jsonableValidation(~output, ~parent=output, ~path=Path.empty, ~flag)
2113-
}
2114-
2115-
let input = {
2116-
b,
2117-
var: B._var,
2118-
inline: Builder.intitialInputVar,
2119-
flag: ValFlag.none,
2120-
schema: if (
2121-
flag->Flag.unsafeHas(Flag.typeValidation) || schema.tag === unionTag || schema->isLiteral
2122-
) {
2123-
unknown
2124-
} else {
2125-
schema
2126-
},
2127-
}
2128-
21292107
let schema = if flag->Flag.unsafeHas(Flag.assertOutput) {
21302108
schema
21312109
->updateOutput(mut => {
2132-
let t = base(unit.tag)
2133-
t.const = unit.const
2110+
let t = unit->copySchema
21342111
t.noValidation = Some(true)
21352112
mut.to = Some(t)
21362113
})
@@ -2141,10 +2118,30 @@ and internalCompile = (~schema, ~flag, ~defs) => {
21412118
mut.to = Some(jsonString)
21422119
})
21432120
->castToInternal
2121+
} else if flag->Flag.unsafeHas(Flag.jsonableOutput) {
2122+
schema
2123+
->updateOutput(mut => {
2124+
mut.to = Some(json)
2125+
})
2126+
->castToInternal
21442127
} else {
21452128
schema
21462129
}
21472130

2131+
let input = {
2132+
b,
2133+
var: B._var,
2134+
inline: Builder.intitialInputVar,
2135+
flag: ValFlag.none,
2136+
schema: if (
2137+
flag->Flag.unsafeHas(Flag.typeValidation) || schema.tag === unionTag || schema->isLiteral
2138+
) {
2139+
unknown
2140+
} else {
2141+
schema
2142+
},
2143+
}
2144+
21482145
let output = parse(b, ~schema, ~input, ~path=Path.empty)
21492146

21502147
let code = b->B.allocateScope(~input)
@@ -2473,8 +2470,13 @@ let objectDecoder = Builder.make((b, ~input, ~selfSchema, ~path) => {
24732470
}
24742471
}
24752472

2476-
// FIXME: Run only for unknown input
2477-
if selfSchema.additionalItems === Some(Strict) {
2473+
if (
2474+
selfSchema.additionalItems === Some(Strict) &&
2475+
switch input.schema.additionalItems->X.Option.getUnsafe {
2476+
| Schema(_) => true
2477+
| _ => false
2478+
}
2479+
) {
24782480
let key = b->B.allocateVal(~schema=unknown)
24792481
let keyVar = key.inline
24802482
b.code = b.code ++ `for(${keyVar} in ${b->B.Val.var(input)}){if(`
@@ -4034,8 +4036,6 @@ module String = {
40344036
let datetimeRe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/
40354037
}
40364038

4037-
let json = shaken("json")
4038-
40394039
let jsonEncoder = Builder.make((b, ~input, ~selfSchema as to, ~path) => {
40404040
let toTagFlag = to.tag->TagFlag.get
40414041

@@ -4105,6 +4105,25 @@ let jsonDecoder = Builder.make((b, ~input, ~selfSchema, ~path) => {
41054105
},
41064106
)
41074107
Array.arrayDecoder(b, ~input, ~selfSchema=mut, ~path)
4108+
} else if inputTagFlag->Flag.unsafeHas(TagFlag.object) {
4109+
let mut = base(objectTag)
4110+
let properties = Js.Dict.empty()
4111+
mut.items = Some(
4112+
input.schema.items
4113+
->X.Option.getUnsafe
4114+
->Js.Array2.map(item => {
4115+
properties->Js.Dict.set(item.location, json)
4116+
{...item, schema: json->castToPublic}
4117+
}),
4118+
)
4119+
mut.properties = Some(properties)
4120+
mut.additionalItems = Some(
4121+
switch input.schema.additionalItems->X.Option.getUnsafe {
4122+
| Schema(_) => Schema(json->castToPublic)
4123+
| v => v
4124+
},
4125+
)
4126+
objectDecoder(b, ~input, ~selfSchema=mut, ~path)
41084127
} else if inputTagFlag->Flag.unsafeHas(TagFlag.unknown) {
41094128
let to = selfSchema.to->X.Option.getUnsafe
41104129
// Whether we can optimize encoding during decoding
@@ -4183,31 +4202,35 @@ let enableJsonString = {
41834202
}
41844203

41854204
let makeJsonStringEncoder = (~validateOnly) =>
4186-
Builder.make((b, ~input, ~selfSchema, ~path) => {
4187-
let inputVar = b->B.Val.var(input)
4188-
let output = ref(input)
4189-
b.code =
4190-
b.code ++
4191-
`try{` ++
4192-
if validateOnly {
4193-
""
4194-
} else {
4195-
let targetVal = b->B.allocateVal(~schema=json)
4196-
output := targetVal
4197-
targetVal.inline ++ "="
4198-
} ++
4199-
`JSON.parse(${inputVar})}catch(t){${b->B.failWithArg(
4200-
~path,
4201-
input => InvalidType({
4202-
expected: selfSchema->castToPublic,
4203-
received: input,
4204-
}),
4205-
inputVar,
4206-
)}}`
4207-
if !validateOnly {
4208-
output := jsonEncoder(b, ~input=output.contents, ~selfSchema, ~path)
4205+
Builder.make((b, ~input, ~selfSchema as to, ~path) => {
4206+
if to.format === Some(JSON) {
4207+
input
4208+
} else {
4209+
let inputVar = b->B.Val.var(input)
4210+
let output = ref(input)
4211+
b.code =
4212+
b.code ++
4213+
`try{` ++
4214+
if validateOnly {
4215+
""
4216+
} else {
4217+
let targetVal = b->B.allocateVal(~schema=json)
4218+
output := targetVal
4219+
targetVal.inline ++ "="
4220+
} ++
4221+
`JSON.parse(${inputVar})}catch(t){${b->B.failWithArg(
4222+
~path,
4223+
input => InvalidType({
4224+
expected: to->castToPublic,
4225+
received: input,
4226+
}),
4227+
inputVar,
4228+
)}}`
4229+
if !validateOnly {
4230+
output := jsonEncoder(b, ~input=output.contents, ~selfSchema=to, ~path)
4231+
}
4232+
output.contents
42094233
}
4210-
output.contents
42114234
})
42124235

42134236
() => {
@@ -4654,45 +4677,45 @@ module Schema = {
46544677
(b, ~input: val, ~selfSchema, ~path) => {
46554678
let isFlatten = b.global.flag->Flag.unsafeHas(Flag.flatten)
46564679
// let outputs = isFlatten ? input.properties->Obj.magic : Js.Dict.empty()
4657-
let outputs = Js.Dict.empty() // FIXME:
4680+
// let outputs = Js.Dict.empty() // FIXME:
46584681

4659-
if !isFlatten {
4660-
let items = selfSchema.items->X.Option.getUnsafe
4682+
// if !isFlatten {
4683+
// let items = selfSchema.items->X.Option.getUnsafe
46614684

4662-
for idx in 0 to items->Js.Array2.length - 1 {
4663-
let {schema, location} = items->Js.Array2.unsafe_get(idx)
4664-
let schema = schema->castToInternal
4685+
// for idx in 0 to items->Js.Array2.length - 1 {
4686+
// let {schema, location} = items->Js.Array2.unsafe_get(idx)
4687+
// let schema = schema->castToInternal
46654688

4666-
let itemInput = b->B.Val.get(input, location)
4667-
let path = path->Path.concat(b->B.inlineLocation(location)->Path.fromInlinedLocation)
4668-
outputs->Js.Dict.set(location, b->parse(~schema, ~input=itemInput, ~path))
4669-
}
4689+
// let itemInput = b->B.Val.get(input, location)
4690+
// let path = path->Path.concat(b->B.inlineLocation(location)->Path.fromInlinedLocation)
4691+
// outputs->Js.Dict.set(location, b->parse(~schema, ~input=itemInput, ~path))
4692+
// }
46704693

4671-
b->objectStrictModeCheck(~input, ~items, ~selfSchema, ~path)
4672-
}
4694+
// b->objectStrictModeCheck(~input, ~items, ~selfSchema, ~path)
4695+
// }
46734696

4674-
switch flattened {
4675-
| None => ()
4676-
| Some(rootItems) =>
4677-
let prevFlag = b.global.flag
4678-
b.global.flag = prevFlag->Flag.with(Flag.flatten)
4679-
for idx in 0 to rootItems->Js.Array2.length - 1 {
4680-
let item = rootItems->Js.Array2.unsafe_get(idx)
4681-
outputs
4682-
->Js.Dict.set(
4683-
item->getUnsafeDitemIndex,
4684-
b->parse(~schema=item->getDitemSchema, ~input, ~path),
4685-
)
4686-
->ignore
4687-
}
4688-
b.global.flag = prevFlag
4689-
}
4697+
// switch flattened {
4698+
// | None => ()
4699+
// | Some(rootItems) =>
4700+
// let prevFlag = b.global.flag
4701+
// b.global.flag = prevFlag->Flag.with(Flag.flatten)
4702+
// for idx in 0 to rootItems->Js.Array2.length - 1 {
4703+
// let item = rootItems->Js.Array2.unsafe_get(idx)
4704+
// outputs
4705+
// ->Js.Dict.set(
4706+
// item->getUnsafeDitemIndex,
4707+
// b->parse(~schema=item->getDitemSchema, ~input, ~path),
4708+
// )
4709+
// ->ignore
4710+
// }
4711+
// b.global.flag = prevFlag
4712+
// }
46904713

46914714
let rec getItemOutput = item => {
46924715
switch item {
46934716
| ItemField({target: item, location}) => b->B.Val.get(item->getItemOutput, location)
4694-
| Item({location}) => outputs->Js.Dict.unsafeGet(location)
4695-
| Root({idx}) => outputs->Js.Dict.unsafeGet(idx->X.Int.unsafeToString)
4717+
| Item({location}) => b->B.Val.get(input, location)
4718+
| Root({idx}) => b->B.Val.get(input, idx->X.Int.unsafeToString)
46964719
}
46974720
}
46984721

@@ -5080,6 +5103,7 @@ module Schema = {
50805103
mut.items = Some(items)
50815104
mut.properties = Some(properties)
50825105
mut.additionalItems = Some(globalConfig.defaultAdditionalItems)
5106+
mut.decoder = Some(objectDecoder)
50835107
mut.parser = Some(advancedBuilder(~definition, ~flattened))
50845108
mut.to = Some(definitionToTarget(~definition, ~flattened))
50855109
mut->castToPublic
@@ -5130,6 +5154,7 @@ module Schema = {
51305154
let mut = base(arrayTag)
51315155
mut.items = Some(items)
51325156
mut.additionalItems = Some(Strict)
5157+
mut.decoder = Some(Array.arrayDecoder)
51335158
mut.parser = Some(advancedBuilder(~definition))
51345159
mut.to = Some(definitionToTarget(~definition))
51355160
mut->castToPublic

0 commit comments

Comments
 (0)