Module: RubynCode::IDE::Protocol

Defined in:
lib/rubyn_code/ide/protocol.rb

Overview

JSON-RPC 2.0 protocol layer for the IDE server. Pure data — no side effects, no I/O beyond JSON serialisation.

Defined Under Namespace

Classes: JsonRpcError

Constant Summary collapse

JSONRPC_VERSION =
'2.0'
PARSE_ERROR =

── Standard JSON-RPC 2.0 error codes ──────────────────────────────

-32_700
INVALID_REQUEST =
-32_600
METHOD_NOT_FOUND =
-32_601
INVALID_PARAMS =
-32_602
INTERNAL_ERROR =
-32_603
AGENT_BUSY =

── Custom error codes ─────────────────────────────────────────────

-1
SESSION_NOT_FOUND =
-2
BUDGET_EXCEEDED =
-3

Class Method Summary collapse

Class Method Details

.error(id, code, message) ⇒ Object

Build an error response hash.



82
83
84
85
86
87
88
89
90
91
# File 'lib/rubyn_code/ide/protocol.rb', line 82

def error(id, code, message)
  {
    'jsonrpc' => JSONRPC_VERSION,
    'id' => id,
    'error' => {
      'code' => code,
      'message' => message
    }
  }
end

.notification(method, params) ⇒ Object

Build a notification hash (no id).



94
95
96
97
98
99
100
# File 'lib/rubyn_code/ide/protocol.rb', line 94

def notification(method, params)
  {
    'jsonrpc' => JSONRPC_VERSION,
    'method' => method,
    'params' => stringify_keys_deep(params)
  }
end

.parse(line) ⇒ Object

Parse a JSON string into a request hash. Returns either a valid request hash or an error response hash. – JSON-RPC validation checks



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rubyn_code/ide/protocol.rb', line 44

def parse(line)
  begin
    data = JSON.parse(line)
  rescue JSON::ParserError
    return error(nil, PARSE_ERROR, 'Parse error: invalid JSON')
  end

  return error(nil, INVALID_REQUEST, 'Invalid request: expected JSON object') unless data.is_a?(Hash)

  unless data['jsonrpc'] == JSONRPC_VERSION
    return error(data['id'], INVALID_REQUEST, 'Invalid request: missing or wrong "jsonrpc" version')
  end

  # Response objects (containing "result" or "error") are valid
  # JSON-RPC 2.0 messages that don't carry a "method".
  is_response = data.key?('result') || data.key?('error')

  unless is_response || data['method'].is_a?(String)
    return error(data['id'], INVALID_REQUEST, 'Invalid request: "method" must be a string')
  end

  if data.key?('params') && !data['params'].is_a?(Hash) && !data['params'].is_a?(Array)
    return error(data['id'], INVALID_PARAMS, 'Invalid params: "params" must be an object or array')
  end

  data
end

.response(id, result) ⇒ Object

Build a success response hash.



73
74
75
76
77
78
79
# File 'lib/rubyn_code/ide/protocol.rb', line 73

def response(id, result)
  {
    'jsonrpc' => JSONRPC_VERSION,
    'id' => id,
    'result' => stringify_keys_deep(result)
  }
end

.serialize(hash) ⇒ Object

Serialise a hash to a JSON string terminated by a newline.



103
104
105
# File 'lib/rubyn_code/ide/protocol.rb', line 103

def serialize(hash)
  "#{JSON.generate(hash)}\n"
end