mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
* feat(mcp-server): 增加mcclient sdk适配器结构体以及对应的认证方法 * feat(mcp-server): 增加资源查询的sdk适配器方法 * feat(mcp-server): 增加资源操作的sdk适配器方法 * feat(mcp-server): 增加区域资源查询工具 * feat(mcp-server): 增加网络资源查询工具 * feat(mcp-server): 增加镜像资源查询工具 * feat(mcp-server): 增加虚拟机资源查询工具 * feat(mcp-server): 增加vpc资源查询工具 * feat(mcp-server): 增加存储资源查询工具 * feat(mcp-server): 增加套餐资源查询工具 * feat(mcp-server): 增加虚拟机创建工具 * feat(mcp-server): 增加虚拟机监控工具 * feat(mcp-server): 增加虚拟机操作工具,包括启动、重启、停止、重置密码和删除 * optimize(mcp-server): 增加工具函数接口定义 * feat(mcp-server): 增加工具函数所使用的结构体模型 * feat(mcp-server): 新增工具统一注册中心 * feat(mcp-server): 增加mcp服务中心 * feat(mcp-server): 增加统一配置中心 * feat(mcp-server): 增加服务启动主入口 * doc(mcp-server): 增加mcp-server相关的说明,安装和使用文档 * fix(mcp-server): 更正文档位置以及补充图片 * refactor(mcp-server): 修正了service以及配置解析的逻辑 * refactor(mcp-server): 将日志打印相关代码改成使用log * feat(mcp-server): 增加mcclient sdk适配器结构体以及对应的认证方法 * feat(mcp-server): 增加资源查询的sdk适配器方法 * feat(mcp-server): 增加资源操作的sdk适配器方法 * feat(mcp-server): 增加区域资源查询工具 * feat(mcp-server): 增加网络资源查询工具 * feat(mcp-server): 增加镜像资源查询工具 * feat(mcp-server): 增加虚拟机资源查询工具 * feat(mcp-server): 增加vpc资源查询工具 * feat(mcp-server): 增加存储资源查询工具 * feat(mcp-server): 增加套餐资源查询工具 * feat(mcp-server): 增加虚拟机创建工具 * feat(mcp-server): 增加虚拟机监控工具 * feat(mcp-server): 增加虚拟机操作工具,包括启动、重启、停止、重置密码和删除 * optimize(mcp-server): 增加工具函数接口定义 * feat(mcp-server): 增加工具函数所使用的结构体模型 * feat(mcp-server): 新增工具统一注册中心 * feat(mcp-server): 增加mcp服务中心 * feat(mcp-server): 增加统一配置中心 * feat(mcp-server): 增加服务启动主入口 * doc(mcp-server): 增加mcp-server相关的说明,安装和使用文档 * fix(mcp-server): 更正文档位置以及补充图片 * refactor(mcp-server): 修正了service以及配置解析的逻辑 * refactor(mcp-server): 将日志打印相关代码改成使用log * fix(mcp-server): 修复依赖导入以及缺失等问题 * refactor(mcp-server): 复用common_options * fix: 修复配置结构体字段重复的问题 * doc(mcp-server): 更正文档错误 * style(mcp-server): 格式化import顺序 * style(mcp-server): 格式化import导入 * style(mcp-server): 规范import语句 * doc(mcp-server): 给目录生成doc文件 --------- Co-authored-by: 屈轩 <qu_xuan@icloud.com>
183 lines
4.4 KiB
Go
183 lines
4.4 KiB
Go
package orderedmap
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding"
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"unicode/utf8"
|
|
|
|
"github.com/buger/jsonparser"
|
|
"github.com/mailru/easyjson/jwriter"
|
|
)
|
|
|
|
var (
|
|
_ json.Marshaler = &OrderedMap[int, any]{}
|
|
_ json.Unmarshaler = &OrderedMap[int, any]{}
|
|
)
|
|
|
|
// MarshalJSON implements the json.Marshaler interface.
|
|
func (om *OrderedMap[K, V]) MarshalJSON() ([]byte, error) { //nolint:funlen
|
|
if om == nil || om.list == nil {
|
|
return []byte("null"), nil
|
|
}
|
|
|
|
writer := jwriter.Writer{}
|
|
writer.RawByte('{')
|
|
|
|
for pair, firstIteration := om.Oldest(), true; pair != nil; pair = pair.Next() {
|
|
if firstIteration {
|
|
firstIteration = false
|
|
} else {
|
|
writer.RawByte(',')
|
|
}
|
|
|
|
switch key := any(pair.Key).(type) {
|
|
case string:
|
|
writer.String(key)
|
|
case encoding.TextMarshaler:
|
|
writer.RawByte('"')
|
|
writer.Raw(key.MarshalText())
|
|
writer.RawByte('"')
|
|
case int:
|
|
writer.IntStr(key)
|
|
case int8:
|
|
writer.Int8Str(key)
|
|
case int16:
|
|
writer.Int16Str(key)
|
|
case int32:
|
|
writer.Int32Str(key)
|
|
case int64:
|
|
writer.Int64Str(key)
|
|
case uint:
|
|
writer.UintStr(key)
|
|
case uint8:
|
|
writer.Uint8Str(key)
|
|
case uint16:
|
|
writer.Uint16Str(key)
|
|
case uint32:
|
|
writer.Uint32Str(key)
|
|
case uint64:
|
|
writer.Uint64Str(key)
|
|
default:
|
|
|
|
// this switch takes care of wrapper types around primitive types, such as
|
|
// type myType string
|
|
switch keyValue := reflect.ValueOf(key); keyValue.Type().Kind() {
|
|
case reflect.String:
|
|
writer.String(keyValue.String())
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
writer.Int64Str(keyValue.Int())
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
writer.Uint64Str(keyValue.Uint())
|
|
default:
|
|
return nil, fmt.Errorf("unsupported key type: %T", key)
|
|
}
|
|
}
|
|
|
|
writer.RawByte(':')
|
|
// the error is checked at the end of the function
|
|
writer.Raw(json.Marshal(pair.Value)) //nolint:errchkjson
|
|
}
|
|
|
|
writer.RawByte('}')
|
|
|
|
return dumpWriter(&writer)
|
|
}
|
|
|
|
func dumpWriter(writer *jwriter.Writer) ([]byte, error) {
|
|
if writer.Error != nil {
|
|
return nil, writer.Error
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
buf.Grow(writer.Size())
|
|
if _, err := writer.DumpTo(&buf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// UnmarshalJSON implements the json.Unmarshaler interface.
|
|
func (om *OrderedMap[K, V]) UnmarshalJSON(data []byte) error {
|
|
if om.list == nil {
|
|
om.initialize(0)
|
|
}
|
|
|
|
return jsonparser.ObjectEach(
|
|
data,
|
|
func(keyData []byte, valueData []byte, dataType jsonparser.ValueType, offset int) error {
|
|
if dataType == jsonparser.String {
|
|
// jsonparser removes the enclosing quotes; we need to restore them to make a valid JSON
|
|
valueData = data[offset-len(valueData)-2 : offset]
|
|
}
|
|
|
|
var key K
|
|
var value V
|
|
|
|
switch typedKey := any(&key).(type) {
|
|
case *string:
|
|
s, err := decodeUTF8(keyData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*typedKey = s
|
|
case encoding.TextUnmarshaler:
|
|
if err := typedKey.UnmarshalText(keyData); err != nil {
|
|
return err
|
|
}
|
|
case *int, *int8, *int16, *int32, *int64, *uint, *uint8, *uint16, *uint32, *uint64:
|
|
if err := json.Unmarshal(keyData, typedKey); err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
// this switch takes care of wrapper types around primitive types, such as
|
|
// type myType string
|
|
switch reflect.TypeOf(key).Kind() {
|
|
case reflect.String:
|
|
s, err := decodeUTF8(keyData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
convertedKeyData := reflect.ValueOf(s).Convert(reflect.TypeOf(key))
|
|
reflect.ValueOf(&key).Elem().Set(convertedKeyData)
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
if err := json.Unmarshal(keyData, &key); err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
return fmt.Errorf("unsupported key type: %T", key)
|
|
}
|
|
}
|
|
|
|
if err := json.Unmarshal(valueData, &value); err != nil {
|
|
return err
|
|
}
|
|
|
|
om.Set(key, value)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func decodeUTF8(input []byte) (string, error) {
|
|
remaining, offset := input, 0
|
|
runes := make([]rune, 0, len(remaining))
|
|
|
|
for len(remaining) > 0 {
|
|
r, size := utf8.DecodeRune(remaining)
|
|
if r == utf8.RuneError && size <= 1 {
|
|
return "", fmt.Errorf("not a valid UTF-8 string (at position %d): %s", offset, string(input))
|
|
}
|
|
|
|
runes = append(runes, r)
|
|
remaining = remaining[size:]
|
|
offset += size
|
|
}
|
|
|
|
return string(runes), nil
|
|
}
|