yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-json-rpc.h" 2 3#include "slang-com-helper.h" 4#include "slang-json-native.h" 5 6namespace Slang 7{ 8 9// https://www.jsonrpc.org/specification 10 11 12/* static */ const UnownedStringSlice JSONRPC ::jsonRpc = UnownedStringSlice ::fromLiteral ("jsonrpc" ); 13/* static */ const UnownedStringSlice JSONRPC ::jsonRpcVersion = 14UnownedStringSlice ::fromLiteral ("2.0" ); 15/* static */ const UnownedStringSlice JSONRPC ::id = UnownedStringSlice ::fromLiteral ("id" ); 16 17static const auto g_result = UnownedStringSlice ::fromLiteral ("result" ); 18static const auto g_error = UnownedStringSlice ::fromLiteral ("error" ); 19static const auto g_method = UnownedStringSlice ::fromLiteral ("method" ); 20 21// Add the fields. 22// TODO(JS): This is a little verbose, and could be improved on with something like 23// * Tool that automatically generated from C++ (say via the C++ extractor) 24// * Macro magic to simplify the construction 25static const StructRttiInfo _makeJSONRPCErrorResponse_ErrorRtti () 26{ 27JSONRPCErrorResponse ::Error obj ; 28StructRttiBuilder builder (& obj ,"JSONRPCErrorResponse::Error" ,nullptr ); 29builder .addField ("code" ,& obj .code ); 30builder .addField ("message" ,& obj .message ); 31return builder .make (); 32} 33/* static */ const StructRttiInfo JSONRPCErrorResponse ::Error ::g_rttiInfo = 34_makeJSONRPCErrorResponse_ErrorRtti (); 35 36static const StructRttiInfo _makeJSONRPCErrorResponseRtti () 37{ 38JSONRPCErrorResponse obj ; 39StructRttiBuilder builder (& obj ,"JSONRPCErrorResponse" ,nullptr ); 40 41builder .addField ("jsonrpc" ,& obj .jsonrpc ); 42builder .addField ("error" ,& obj .error ); 43builder .addField ("data" ,& obj .data ,StructRttiInfo ::Flag ::Optional ); 44builder .addField ("id" ,& obj .id ,StructRttiInfo ::Flag ::Optional ); 45 46return builder .make (); 47} 48/* static */ const StructRttiInfo JSONRPCErrorResponse ::g_rttiInfo = 49_makeJSONRPCErrorResponseRtti (); 50 51static const StructRttiInfo _makeJSONRPCCallResponseRtti () 52{ 53JSONRPCCall obj ; 54StructRttiBuilder builder (& obj ,"JSONRPCCall" ,nullptr ); 55 56builder .addField ("jsonrpc" ,& obj .jsonrpc ); 57builder .addField ("method" ,& obj .method ); 58builder .addField ("params" ,& obj .params ,StructRttiInfo ::Flag ::Optional ); 59builder .addField ("id" ,& obj .id ,StructRttiInfo ::Flag ::Optional ); 60builder .ignoreUnknownFields (); 61 62return builder .make (); 63} 64/* static */ const StructRttiInfo JSONRPCCall ::g_rttiInfo = _makeJSONRPCCallResponseRtti (); 65 66static const StructRttiInfo _makeJSONResultResponseResponseRtti () 67{ 68JSONResultResponse obj ; 69StructRttiBuilder builder (& obj ,"JSONResultResponse" ,nullptr ); 70 71builder .addField ("jsonrpc" ,& obj .jsonrpc ); 72builder .addField ("result" ,& obj .result ); 73builder .addField ("id" ,& obj .id ,StructRttiInfo ::Flag ::Optional ); 74 75return builder .make (); 76} 77/* static */ const StructRttiInfo JSONResultResponse ::g_rttiInfo = 78_makeJSONResultResponseResponseRtti (); 79 80/* static */ JSONRPCMessageType JSONRPCUtil ::getMessageType ( 81JSONContainer * container , 82const JSONValue & value ) 83{ 84if (value .getKind ()== JSONValue ::Kind ::Object ) 85 { 86const JSONKey resultKey = container -> findKey (g_result ); 87const JSONKey errorKey = container -> findKey (g_error ); 88const JSONKey methodKey = container -> findKey (g_method ); 89 90auto pairs = container -> getObject (value ); 91 92for (const auto & pair :pairs ) 93 { 94if (pair .key == resultKey ) 95 { 96return JSONRPCMessageType ::Result ; 97 } 98else if (pair .key == errorKey ) 99 { 100return JSONRPCMessageType ::Error ; 101 } 102else if (pair .key == methodKey ) 103 { 104return JSONRPCMessageType ::Call ; 105 } 106 } 107 } 108 109return JSONRPCMessageType ::Invalid ; 110} 111 112/* static */ SlangResult JSONRPCUtil ::parseJSON ( 113const UnownedStringSlice & slice , 114JSONContainer * container , 115DiagnosticSink * sink , 116JSONValue & outValue ) 117{ 118SourceManager * sourceManager = sink -> getSourceManager (); 119 120// Now need to parse as JSON 121String contents (slice ); 122SourceFile * sourceFile = 123sourceManager -> createSourceFileWithString (PathInfo ::makeUnknown (),contents ); 124SourceView * sourceView = sourceManager -> createSourceView (sourceFile ,nullptr ,SourceLoc ()); 125 126JSONLexer lexer ; 127lexer .init (sourceView ,sink ); 128 129JSONBuilder builder (container ); 130 131JSONParser parser ; 132SLANG_RETURN_ON_FAIL (parser .parse (& lexer ,sourceView ,& builder ,sink )); 133 134outValue = builder .getRootValue (); 135return SLANG_OK ; 136} 137 138/* static */ SlangResult JSONRPCUtil ::convertToNative ( 139JSONContainer * container , 140const JSONValue & value , 141DiagnosticSink * sink , 142const RttiInfo * rttiInfo , 143void * out ) 144{ 145auto typeMap = JSONNativeUtil ::getTypeFuncsMap (); 146 147JSONToNativeConverter converter (container ,& typeMap ,sink ); 148SLANG_RETURN_ON_FAIL (converter .convert (value ,rttiInfo ,out )); 149return SLANG_OK ; 150} 151 152/* static */ SlangResult JSONRPCUtil ::convertToJSON ( 153const RttiInfo * rttiInfo , 154const void * in , 155DiagnosticSink * sink , 156StringBuilder & out ) 157{ 158SourceManager * sourceManager = sink -> getSourceManager (); 159JSONContainer container (sourceManager ); 160 161auto typeMap = JSONNativeUtil ::getTypeFuncsMap (); 162 163NativeToJSONConverter converter (& container ,& typeMap ,sink ); 164 165JSONValue value ; 166SLANG_RETURN_ON_FAIL (converter .convert (rttiInfo ,in ,value )); 167 168// Convert into a string 169JSONWriter writer (JSONWriter ::IndentationStyle ::Allman ); 170container .traverseRecursively (value ,& writer ); 171 172out = writer .getBuilder (); 173return SLANG_OK ; 174} 175 176/* static */ JSONValue JSONRPCUtil ::getId (JSONContainer * container ,const JSONValue & root ) 177{ 178if (root .getKind ()== JSONValue ::Kind ::Object ) 179 { 180const JSONKey key = container -> findKey (JSONRPC ::id ); 181 182if (key != JSONKey (0 )) 183 { 184auto obj = container -> getObject (root ); 185Index index = obj .findFirstIndex ( 186 [key ](const JSONKeyValue & pair )-> bool {return pair .key == key ; }); 187 188if (index >=0 ) 189 { 190return obj [index ].value ; 191 } 192 } 193 } 194return JSONValue (); 195} 196 197 198}// namespace Slang