diff --git a/include/dap/session.h b/include/dap/session.h index f6cbb8b..b37d297 100644 --- a/include/dap/session.h +++ b/include/dap/session.h @@ -201,7 +201,8 @@ class Session { virtual void registerHandler(const TypeInfo* typeinfo, const GenericResponseSentHandler& handler) = 0; - virtual bool send(const dap::TypeInfo* typeinfo, + virtual bool send(const dap::TypeInfo* requestTypeInfo, + const dap::TypeInfo* responseTypeInfo, const void* request, const GenericResponseHandler& responseHandler) = 0; @@ -251,9 +252,9 @@ template future> Session::send(const T& request) { using Response = typename T::Response; promise> promise; - const TypeInfo* typeinfo = TypeOf::type(); - auto sent = - send(typeinfo, &request, [=](const void* result, const Error* error) { + auto sent = send( + TypeOf::type(), TypeOf::type(), &request, + [=](const void* result, const Error* error) { if (error != nullptr) { promise.set_value(ResponseOrError(*error)); } else { diff --git a/src/session.cpp b/src/session.cpp index 57c8c9a..78b0a57 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -80,19 +80,20 @@ class Impl : public dap::Session { }); } - bool send(const dap::TypeInfo* typeinfo, + bool send(const dap::TypeInfo* requestTypeInfo, + const dap::TypeInfo* responseTypeInfo, const void* request, const GenericResponseHandler& responseHandler) override { int seq = nextSeq++; - handlers.put(seq, typeinfo, responseHandler); + handlers.put(seq, responseTypeInfo, responseHandler); dap::json::Serializer s; s.field("seq", dap::integer(seq)); s.field("type", "request"); - s.field("command", typeinfo->name()); + s.field("command", requestTypeInfo->name()); s.field("arguments", [&](dap::Serializer* s) { - return typeinfo->serialize(s, request); + return requestTypeInfo->serialize(s, request); }); return send(s.dump()); } @@ -411,12 +412,11 @@ class Impl : public dap::Session { auto data = std::unique_ptr(new uint8_t[typeinfo->size()]); typeinfo->construct(data.get()); - if (!d->field("body", [&](const dap::Deserializer* d) { - return typeinfo->deserialize(d, data.get()); - })) { - handlers.error("Failed to deserialize request"); - return; - } + // "body" field in Response is an optional field. + d->field("body", [&](const dap::Deserializer* d) { + return typeinfo->deserialize(d, data.get()); + }); + handler(data.get(), nullptr); typeinfo->destruct(data.get()); diff --git a/src/session_test.cpp b/src/session_test.cpp index 66974fa..6b072e2 100644 --- a/src/session_test.cpp +++ b/src/session_test.cpp @@ -54,7 +54,7 @@ DAP_STRUCT_TYPEINFO(TestResponse, struct TestRequest : public Request { using Response = TestResponse; - boolean b; + boolean req_b; integer i; number n; array a; @@ -66,7 +66,7 @@ struct TestRequest : public Request { DAP_STRUCT_TYPEINFO(TestRequest, "test-request", - DAP_FIELD(b, "b"), + DAP_FIELD(req_b, "req_b"), DAP_FIELD(i, "i"), DAP_FIELD(n, "n"), DAP_FIELD(a, "a"), @@ -103,7 +103,7 @@ namespace { dap::TestRequest createRequest() { dap::TestRequest request; - request.b = false; + request.req_b = false; request.i = 72; request.n = 9.87; request.a = {2, 5, 7, 8}; @@ -177,7 +177,7 @@ TEST_F(SessionTest, Request) { client->send(request).get(); // Check request was received correctly. - ASSERT_EQ(received.b, request.b); + ASSERT_EQ(received.req_b, request.req_b); ASSERT_EQ(received.i, request.i); ASSERT_EQ(received.n, request.n); ASSERT_EQ(received.a, request.a); @@ -219,6 +219,30 @@ TEST_F(SessionTest, RequestResponseSuccess) { ASSERT_FALSE(got.response.o2.has_value()); } +TEST_F(SessionTest, BreakPointRequestResponseSuccess) { + server->registerHandler( + [&](const dap::SetBreakpointsRequest&) { + dap::SetBreakpointsResponse rsp; + dap::array breakpoints; + dap::Breakpoint bpItem; + bpItem.line = 2; + breakpoints.emplace_back(std::move(bpItem)); + rsp.breakpoints.swap(breakpoints); + return rsp; + }); + + bind(); + + dap::SetBreakpointsRequest request; + auto response = client->send(request); + + auto got = response.get(); + + // Check response was received correctly. + ASSERT_EQ(got.error, false); + ASSERT_EQ(got.response.breakpoints.size(), 1); + +} TEST_F(SessionTest, RequestResponseOrError) { server->registerHandler( [&](const dap::TestRequest&) -> dap::ResponseOrError {