Skip to content

Commit e1f281f

Browse files
committed
add typed json rpc messages
1 parent dd46b5e commit e1f281f

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

src/lsp.zig

+126
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,132 @@ pub const JsonRPCMessage = union(enum) {
821821
}
822822
};
823823

824+
pub fn TypedJsonRPCRequest(
825+
/// Must serialize to a JSON Array, JSON Object or JSON null.
826+
comptime Params: type,
827+
) type {
828+
return struct {
829+
comptime jsonrpc: []const u8 = "2.0",
830+
/// The request id.
831+
id: JsonRPCMessage.ID,
832+
/// The method to be invoked.
833+
method: []const u8,
834+
/// The requests's params. `params == null` means means no `"params"` field.
835+
params: ?Params,
836+
837+
pub fn jsonStringify(request: @This(), stream: anytype) @TypeOf(stream.*).Error!void {
838+
try stream.beginObject();
839+
840+
try stream.objectField("jsonrpc");
841+
try stream.write("2.0");
842+
843+
try stream.objectField("id");
844+
try stream.write(request.id);
845+
846+
try stream.objectField("method");
847+
try stream.write(request.method);
848+
849+
if (request.params) |params| {
850+
try stream.objectField("params");
851+
switch (@TypeOf(params)) {
852+
void,
853+
?void,
854+
=> try stream.write(null),
855+
else => try stream.write(params),
856+
}
857+
} else if (stream.options.emit_null_optional_fields) {
858+
try stream.objectField("params");
859+
try stream.write(null);
860+
}
861+
862+
try stream.endObject();
863+
}
864+
};
865+
}
866+
867+
pub fn TypedJsonRPCNotification(
868+
/// Must serialize to a JSON Array, JSON Object or JSON null.
869+
comptime Params: type,
870+
) type {
871+
return struct {
872+
comptime jsonrpc: []const u8 = "2.0",
873+
/// The method to be invoked.
874+
method: []const u8,
875+
/// The requests's params. `params == null` means means no `"params"` field.
876+
params: ?Params,
877+
878+
pub fn jsonStringify(notification: @This(), stream: anytype) @TypeOf(stream.*).Error!void {
879+
try stream.beginObject();
880+
881+
try stream.objectField("jsonrpc");
882+
try stream.write("2.0");
883+
884+
try stream.objectField("method");
885+
try stream.write(notification.method);
886+
887+
if (notification.params) |params| {
888+
try stream.objectField("params");
889+
switch (@TypeOf(params)) {
890+
void,
891+
?void,
892+
=> try stream.write(null),
893+
else => try stream.write(params),
894+
}
895+
} else if (stream.options.emit_null_optional_fields) {
896+
try stream.objectField("params");
897+
try stream.write(null);
898+
}
899+
900+
try stream.endObject();
901+
}
902+
};
903+
}
904+
905+
pub fn TypedJsonRPCResponse(
906+
/// Must serialize to a JSON Array, JSON Object or JSON null.
907+
comptime Result: type,
908+
) type {
909+
return struct {
910+
/// The request id.
911+
///
912+
/// It must be the same as the value of the `id` member in the `Request` object.
913+
/// If there was an error in detecting the id in the `Request` object (e.g. `Error.Code.parse_error`/`Error.Code.invalid_request`), it must be `null`.
914+
id: ?JsonRPCMessage.ID,
915+
/// The result of a request.
916+
result: ?Result,
917+
918+
pub fn jsonStringify(response: @This(), stream: anytype) @TypeOf(stream.*).Error!void {
919+
try stream.beginObject();
920+
921+
try stream.objectField("jsonrpc");
922+
try stream.write("2.0");
923+
924+
if (response.id) |id| {
925+
try stream.objectField("id");
926+
try stream.write(id);
927+
} else if (stream.options.emit_null_optional_fields) {
928+
try stream.objectField("id");
929+
try stream.write(null);
930+
}
931+
932+
if (response.result) |result| {
933+
try stream.objectField("result");
934+
switch (@TypeOf(result)) {
935+
void,
936+
?void,
937+
=> try stream.write(null),
938+
else => try stream.write(result),
939+
}
940+
} else {
941+
try stream.objectField("result");
942+
try stream.write(null);
943+
}
944+
945+
try stream.endObject();
946+
}
947+
};
948+
}
949+
824950
/// A minimal non-allocating parser for the LSP Base Protocol Header Part.
825951
///
826952
/// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#headerPart

0 commit comments

Comments
 (0)