import 'package:fis_jsonrpc/utils.dart'; class JsonRpcRequest { static const String _serverVersion = '2.0'; final String method; final Object? args; final bool notify; int? get id => !this.notify ? this.hashCode : null; JsonRpcRequest(this.method, this.args, {this.notify = false}); Map toJson() { var map = {}; map = { 'jsonrpc': _serverVersion, 'method': method, 'params': _buildParams(), }; if (!notify) map['id'] = id; return map; } bool _isComplexType(dynamic v) { if (v is String) return false; if (v is num) return false; if (v is bool) return false; if (v is Symbol) return false; if (v is List) return false; if (v is Map) return false; if (v is Set) return false; return true; } dynamic _doComplexValToJson(dynamic v) { if (v is DateTime) { return JsonRpcUtils.dateFormat(v); } dynamic fn; try { fn = v.toJson; } catch (e) { try { final idx = v.index; fn = () => idx; } catch (e) { fn = () => null; } } return fn(); } List _buildListParams() { final arr = (args as List); for (var i = 0; i < arr.length; i++) { final v = arr[i]; if (_isComplexType(v)) { arr[i] = _doComplexValToJson(v); } } return arr; } Map _buildMapParams() { final map = (args as Map); map.forEach((k, v) { if (_isComplexType(v)) { map[k] = _doComplexValToJson(v); } }); return map; } List _buildSetParams() { final set = (args as Set); final arr = []; set.forEach((v) { if (_isComplexType(v)) { arr.add(_doComplexValToJson(v)); } else { arr.add(v); } }); return arr; } dynamic _buildParams() { if (args == null) return []; if (args is List) { return _buildListParams(); } if (args is Map) { return _buildMapParams(); } if (args is Set) { return _buildSetParams(); } return [args]; } @override String toString() => 'JsonRpcRequest: ${toJson()}'; }