Files
彭镜肇 010fdfee3c Pengjingzhao ospp v2 (#23309)
* 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>
2025-09-22 10:32:21 +08:00

174 lines
3.3 KiB
Go

// Copyright (C) 2016 Kohei YOSHIDA. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of The BSD 3-Clause License
// that can be found in the LICENSE file.
package uritemplate
import (
"regexp"
"strconv"
"strings"
)
type template interface {
expand(*strings.Builder, Values) error
regexp(*strings.Builder)
}
type literals string
func (l literals) expand(b *strings.Builder, _ Values) error {
b.WriteString(string(l))
return nil
}
func (l literals) regexp(b *strings.Builder) {
b.WriteString("(?:")
b.WriteString(regexp.QuoteMeta(string(l)))
b.WriteByte(')')
}
type varspec struct {
name string
maxlen int
explode bool
}
type expression struct {
vars []varspec
op parseOp
first string
sep string
named bool
ifemp string
escape escapeFunc
allow runeClass
}
func (e *expression) init() {
switch e.op {
case parseOpSimple:
e.sep = ","
e.escape = escapeExceptU
e.allow = runeClassU
case parseOpPlus:
e.sep = ","
e.escape = escapeExceptUR
e.allow = runeClassUR
case parseOpCrosshatch:
e.first = "#"
e.sep = ","
e.escape = escapeExceptUR
e.allow = runeClassUR
case parseOpDot:
e.first = "."
e.sep = "."
e.escape = escapeExceptU
e.allow = runeClassU
case parseOpSlash:
e.first = "/"
e.sep = "/"
e.escape = escapeExceptU
e.allow = runeClassU
case parseOpSemicolon:
e.first = ";"
e.sep = ";"
e.named = true
e.escape = escapeExceptU
e.allow = runeClassU
case parseOpQuestion:
e.first = "?"
e.sep = "&"
e.named = true
e.ifemp = "="
e.escape = escapeExceptU
e.allow = runeClassU
case parseOpAmpersand:
e.first = "&"
e.sep = "&"
e.named = true
e.ifemp = "="
e.escape = escapeExceptU
e.allow = runeClassU
}
}
func (e *expression) expand(w *strings.Builder, values Values) error {
first := true
for _, varspec := range e.vars {
value := values.Get(varspec.name)
if !value.Valid() {
continue
}
if first {
w.WriteString(e.first)
first = false
} else {
w.WriteString(e.sep)
}
if err := value.expand(w, varspec, e); err != nil {
return err
}
}
return nil
}
func (e *expression) regexp(b *strings.Builder) {
if e.first != "" {
b.WriteString("(?:") // $1
b.WriteString(regexp.QuoteMeta(e.first))
}
b.WriteByte('(') // $2
runeClassToRegexp(b, e.allow, e.named || e.vars[0].explode)
if len(e.vars) > 1 || e.vars[0].explode {
max := len(e.vars) - 1
for i := 0; i < len(e.vars); i++ {
if e.vars[i].explode {
max = -1
break
}
}
b.WriteString("(?:") // $3
b.WriteString(regexp.QuoteMeta(e.sep))
runeClassToRegexp(b, e.allow, e.named || max < 0)
b.WriteByte(')') // $3
if max > 0 {
b.WriteString("{0,")
b.WriteString(strconv.Itoa(max))
b.WriteByte('}')
} else {
b.WriteByte('*')
}
}
b.WriteByte(')') // $2
if e.first != "" {
b.WriteByte(')') // $1
}
b.WriteByte('?')
}
func runeClassToRegexp(b *strings.Builder, class runeClass, named bool) {
b.WriteString("(?:(?:[")
if class&runeClassR == 0 {
b.WriteString(`\x2c`)
if named {
b.WriteString(`\x3d`)
}
}
if class&runeClassU == runeClassU {
b.WriteString(reUnreserved)
}
if class&runeClassR == runeClassR {
b.WriteString(reReserved)
}
b.WriteString("]")
b.WriteString("|%[[:xdigit:]][[:xdigit:]]")
b.WriteString(")*)")
}