Skip to content

Remove Json module #1066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions src/SyntaxLookup.res
Original file line number Diff line number Diff line change
Expand Up @@ -147,24 +147,32 @@ type props = {mdxSources: array<MdxRemote.output>}
type params = {slug: string}

let decode = (json: JSON.t) => {
open Json.Decode
let id = json->field("id", string, _)
let keywords = json->field("keywords", array(string, ...), _)
let name = json->field("name", string, _)
let summary = json->field("summary", string, _)
let category = json->field("category", string, _)->Category.fromString
let status =
json
->optional(field("status", string, _), _)
->Option.mapOr(Status.Active, Status.fromString)

{
id,
keywords,
name,
summary,
category,
status,
open JSON
switch json {
| Object(dict{
"id": String(id),
"keywords": Array(keywords),
"name": String(name),
"summary": String(summary),
"category": String(category),
"status": ?status,
}) => {
id,
name,
summary,
category: Category.fromString(category),
keywords: keywords->Array.filterMap(k =>
switch k {
| String(k) => Some(k)
| _ => None
}
),
status: switch status {
| Some(String(status)) => status->Status.fromString
| _ => Status.Active
},
}
| _ => throw(Failure(`Failed to decode SyntaxLookup. ${__LOC__}`))
}
}

Expand Down
237 changes: 149 additions & 88 deletions src/bindings/RescriptCompilerApi.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ module Lang = {
}

let decode = (json): t => {
open! Json.Decode
switch string(json) {
| "re" => Reason
| "res" => Res
| other => throw(DecodeError(`Unknown language "${other}"`))
open JSON
switch json {
| String("re") => Reason
| String("res") => Res
| other => throw(Failure(`Unknown language "${other->stringify}". ${__LOC__}`))
}
}
}
Expand Down Expand Up @@ -91,14 +91,24 @@ module LocMsg = {
}

let decode = (json): t => {
open Json.Decode
{
fullMsg: json->field("fullMsg", string, _),
shortMsg: json->field("shortMsg", string, _),
row: json->field("row", int, _),
column: json->field("column", int, _),
endRow: json->field("endRow", int, _),
endColumn: json->field("endColumn", int, _),
open JSON
switch json {
| Object(dict{
"fullMsg": String(fullMsg),
"shortMsg": String(shortMsg),
"row": Number(row),
"column": Number(column),
"endRow": Number(endRow),
"endColumn": Number(endColumn),
}) => {
fullMsg,
shortMsg,
row: row->Float.toInt,
column: column->Float.toInt,
endRow: endRow->Float.toInt,
endColumn: endColumn->Float.toInt,
}
| _ => throw(Failure(`Failed to decode LocMsg. ${__LOC__}`))
}
}

Expand Down Expand Up @@ -143,12 +153,18 @@ module Warning = {
| WarnErr({warnNumber: int, details: LocMsg.t}) // Describes an erronous warning

let decode = (json): t => {
open! Json.Decode

let warnNumber = field("warnNumber", int, json)
open JSON
let warnNumber = switch json {
| Object(dict{"warnNumber": Number(warnNumber)}) => warnNumber->Float.toInt
| _ => throw(Failure(`Failed to decode warn number. ${__LOC__}`))
}
let details = LocMsg.decode(json)

field("isError", bool, json) ? WarnErr({warnNumber, details}) : Warn({warnNumber, details})
switch json {
| Object(dict{"isError": Boolean(isError)}) =>
isError ? WarnErr({warnNumber, details}) : Warn({warnNumber, details})
| _ => throw(Failure(`Failed to decode warnings. ${__LOC__}`))
}
}

// Useful for showing errors in a more compact format
Expand Down Expand Up @@ -178,11 +194,14 @@ module WarningFlag = {
}

let decode = (json): t => {
open Json.Decode
{
msg: field("msg", string, json),
warn_flags: field("warn_flags", string, json),
warn_error_flags: field("warn_error_flags", string, json),
open JSON
switch json {
| Object(dict{
"msg": String(msg),
"warn_flags": String(warn_flags),
"warn_error_flags": String(warn_error_flags),
}) => {msg, warn_flags, warn_error_flags}
| _ => throw(Failure(`Failed to decode WarningFlag. ${__LOC__}`))
}
}
}
Expand All @@ -206,27 +225,37 @@ module TypeHint = {
| CoreType(data)

let decodePosition = json => {
open Json.Decode
{
line: field("line", int, json),
col: field("col", int, json),
open JSON
switch json {
| Object(dict{"line": Number(line), "col": Number(col)}) => {
line: line->Float.toInt,
col: col->Float.toInt,
}
| _ => throw(Failure(`Failed to decode position. ${__LOC__}`))
}
}

let decode = (json): t => {
open Json.Decode
let data = {
start: field("start", decodePosition, json),
end: field("end", decodePosition, json),
hint: field("hint", string, json),
open JSON
let data = switch json {
| Object(dict{"start": startPosition, "end": endPosition, "hint": String(hint)}) => {
start: decodePosition(startPosition),
end: decodePosition(endPosition),
hint,
}
| _ => throw(Failure(`Failed to decode type hint position. ${__LOC__}`))
}

switch field("kind", string, json) {
| "expression" => Expression(data)
| "type_declaration" => TypeDeclaration(data)
| "binding" => Binding(data)
| "core_type" => CoreType(data)
| other => throw(DecodeError(`Unknown kind "${other}" type hint`))
switch json {
| Object(dict{"kind": String(kind)}) =>
switch kind {
| "expression" => Expression(data)
| "type_declaration" => TypeDeclaration(data)
| "binding" => Binding(data)
| "core_type" => CoreType(data)
| other => throw(Failure(`Unknown kind "${other}" type hint. ${__LOC__}`))
}
| _ => throw(Failure(`Failed to decode type hint kind. ${__LOC__}`))
}
}
}
Expand All @@ -242,12 +271,17 @@ module CompileSuccess = {
}

let decode = (~time: float, json): t => {
open Json.Decode
{
jsCode: field("js_code", string, json),
warnings: field("warnings", array(Warning.decode, ...), json),
typeHints: withDefault([], field("type_hints", array(TypeHint.decode, ...), ...), json),
time,
open JSON
switch json {
| Object(dict{
"js_code": String(jsCode),
"warnings": Array(warnings),
"type_hints": Array(typeHints),
}) =>
let warnings = warnings->Array.map(Warning.decode)
let typeHints = typeHints->Array.map(TypeHint.decode)
{jsCode, warnings, typeHints, time}
| _ => throw(Failure(`Failed to decode CompileSuccess. ${__LOC__}`))
}
}
}
Expand All @@ -260,11 +294,14 @@ module ConvertSuccess = {
}

let decode = (json): t => {
open Json.Decode
{
code: field("code", string, json),
fromLang: field("fromLang", Lang.decode, json),
toLang: field("toLang", Lang.decode, json),
open JSON
switch json {
| Object(dict{"code": String(code), "fromLang": fromLang, "toLang": toLang}) => {
code,
fromLang: fromLang->Lang.decode,
toLang: toLang->Lang.decode,
}
| _ => throw(Failure(`Failed to decode ConvertSuccess. ${__LOC__}`))
}
}
}
Expand All @@ -278,28 +315,41 @@ module CompileFail = {
| OtherErr(array<LocMsg.t>)

let decode = (json): t => {
open! Json.Decode

switch field("type", string, json) {
| "syntax_error" =>
let locMsgs = field("errors", array(LocMsg.decode, ...), json)
// TODO: There seems to be a bug in the ReScript bundle that reports
// back multiple LocMsgs of the same value
locMsgs->LocMsg.dedupe->SyntaxErr
| "type_error" =>
let locMsgs = field("errors", array(LocMsg.decode, ...), json)
TypecheckErr(locMsgs)
| "warning_error" =>
let warnings = field("errors", array(Warning.decode, ...), json)
WarningErr(warnings)
| "other_error" =>
let locMsgs = field("errors", array(LocMsg.decode, ...), json)
OtherErr(locMsgs)

| "warning_flag_error" =>
let warningFlag = WarningFlag.decode(json)
WarningFlagErr(warningFlag)
| other => throw(DecodeError(`Unknown type "${other}" in CompileFail result`))
open JSON
switch json {
| String(type_) =>
switch type_ {
| "syntax_error" =>
let locMsgs = switch json {
| Object(dict{"erros": Array(errors)}) => errors->Array.map(LocMsg.decode)
| _ => throw(Failure(`Failed to decode erros from syntax_error. ${__LOC__}`))
}
// TODO: There seems to be a bug in the ReScript bundle that reports
// back multiple LocMsgs of the same value
locMsgs->LocMsg.dedupe->SyntaxErr
| "type_error" =>
let locMsgs = switch json {
| Object(dict{"erros": Array(errors)}) => errors->Array.map(LocMsg.decode)
| _ => throw(Failure(`Failed to decode erros from type_error. ${__LOC__}`))
}
TypecheckErr(locMsgs)
| "warning_error" =>
let warnings = switch json {
| Object(dict{"erros": Array(warnings)}) => warnings->Array.map(Warning.decode)
| _ => throw(Failure(`Failed to decode errors from warning_error. ${__LOC__}`))
}
WarningErr(warnings)
| "other_error" =>
let locMsgs = switch json {
| Object(dict{"erros": Array(errors)}) => errors->Array.map(LocMsg.decode)
| _ => throw(Failure(`Failed to decode errors from other_error. ${__LOC__}`))
}
OtherErr(locMsgs)

| "warning_flag_error" => WarningFlagErr(WarningFlag.decode(json))
| other => throw(Failure(`Unknown type "${other}" in CompileFail result. ${__LOC__}`))
}
| _ => throw(Failure(`Failed to decode CompileFail. ${__LOC__}`))
}
}
}
Expand All @@ -313,14 +363,19 @@ module CompilationResult = {

// TODO: We might change this specific api completely before launching
let decode = (~time: float, json: JSON.t): t => {
open! Json.Decode

try switch field("type", string, json) {
| "success" => Success(CompileSuccess.decode(~time, json))
| "unexpected_error" => UnexpectedError(field("msg", string, json))
| _ => Fail(CompileFail.decode(json))
} catch {
| DecodeError(errMsg) => Unknown(errMsg, json)
open JSON
switch json {
| Object(dict{"type": String(type_)}) =>
switch type_ {
| "success" => Success(CompileSuccess.decode(~time, json))
| "unexpected_error" =>
switch json {
| Object(dict{"msg": String(msg)}) => UnexpectedError(msg)
| _ => throw(Failure(`Failed to decode msg from unexpected_error. ${__LOC__}`))
}
| _ => Fail(CompileFail.decode(json))
}
| _ => throw(Failure(`Failed to decode CompilationResult. ${__LOC__}`))
}
}
}
Expand All @@ -333,16 +388,22 @@ module ConversionResult = {
| Unknown(string, JSON.t)

let decode = (~fromLang: Lang.t, ~toLang: Lang.t, json): t => {
open! Json.Decode
try switch field("type", string, json) {
| "success" => Success(ConvertSuccess.decode(json))
| "unexpected_error" => UnexpectedError(field("msg", string, json))
| "syntax_error" =>
let locMsgs = field("errors", array(LocMsg.decode, ...), json)
Fail({fromLang, toLang, details: locMsgs})
| other => Unknown(`Unknown conversion result type "${other}"`, json)
} catch {
| DecodeError(errMsg) => Unknown(errMsg, json)
open JSON
switch json {
| Object(dict{
"type": String(type_),
"msg": ?Some(String(msg)),
"errors": ?Some(Array(errors)),
}) =>
switch type_ {
| "success" => Success(ConvertSuccess.decode(json))
| "unexpected_error" => msg->UnexpectedError
| "syntax_error" =>
let locMsgs = errors->Array.map(LocMsg.decode)
Fail({fromLang, toLang, details: locMsgs})
| other => Unknown(`Unknown conversion result type "${other}"`, json)
}
| _ => throw(Failure(`Failed to decode ConversionResult. ${__LOC__}`))
}
}
}
Expand Down
Loading