mirror of
https://github.com/daeuniverse/dae.git
synced 2025-01-03 21:40:36 +07:00
212 lines
4.1 KiB
Go
212 lines
4.1 KiB
Go
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* Copyright (c) 2022-2023, v2rayA Organization <team@v2raya.org>
|
|
*/
|
|
|
|
package config_parser
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type ItemType int
|
|
|
|
const (
|
|
ItemType_RoutingRule ItemType = iota
|
|
ItemType_Param
|
|
ItemType_Section
|
|
)
|
|
|
|
func (t ItemType) String() string {
|
|
switch t {
|
|
case ItemType_RoutingRule:
|
|
return "RoutingRule"
|
|
case ItemType_Param:
|
|
return "Param"
|
|
case ItemType_Section:
|
|
return "Section"
|
|
default:
|
|
return "<Unknown>"
|
|
}
|
|
}
|
|
|
|
func NewRoutingRuleItem(rule *RoutingRule) *Item {
|
|
return &Item{
|
|
Type: ItemType_RoutingRule,
|
|
Value: rule,
|
|
}
|
|
}
|
|
|
|
func NewParamItem(param *Param) *Item {
|
|
return &Item{
|
|
Type: ItemType_Param,
|
|
Value: param,
|
|
}
|
|
}
|
|
|
|
func NewSectionItem(section *Section) *Item {
|
|
return &Item{
|
|
Type: ItemType_Param,
|
|
Value: section,
|
|
}
|
|
}
|
|
|
|
type Item struct {
|
|
Type ItemType
|
|
Value interface{}
|
|
}
|
|
|
|
func (i *Item) String() string {
|
|
var builder strings.Builder
|
|
builder.WriteString("type: " + i.Type.String() + "\n")
|
|
var content string
|
|
switch val := i.Value.(type) {
|
|
case *RoutingRule:
|
|
content = val.String(false)
|
|
case *Param:
|
|
content = val.String(false)
|
|
case *Section:
|
|
content = val.String()
|
|
default:
|
|
return "<Unknown>\n"
|
|
}
|
|
lines := strings.Split(content, "\n")
|
|
for i := range lines {
|
|
lines[i] = "\t" + lines[i]
|
|
}
|
|
builder.WriteString(strings.Join(lines, "\n"))
|
|
return builder.String()
|
|
}
|
|
|
|
type Section struct {
|
|
Name string
|
|
Items []*Item
|
|
}
|
|
|
|
func (s *Section) String() string {
|
|
var builder strings.Builder
|
|
builder.WriteString("section: " + s.Name + "\n")
|
|
var strItemList []string
|
|
for _, item := range s.Items {
|
|
lines := strings.Split(item.String(), "\n")
|
|
for i := range lines {
|
|
lines[i] = "\t" + lines[i]
|
|
}
|
|
strItemList = append(strItemList, strings.Join(lines, "\n"))
|
|
}
|
|
builder.WriteString(strings.Join(strItemList, "\n"))
|
|
return builder.String()
|
|
}
|
|
|
|
type Param struct {
|
|
// Key may be empty.
|
|
Key string
|
|
|
|
// Either Val or AndFunctions is empty.
|
|
Val string
|
|
AndFunctions []*Function
|
|
}
|
|
|
|
func (p *Param) String(compact bool) string {
|
|
if p.Key == "" {
|
|
return p.Val
|
|
}
|
|
if p.AndFunctions != nil {
|
|
a := paramAndFunctions{
|
|
Key: p.Key,
|
|
AndFunctions: p.AndFunctions,
|
|
}
|
|
return a.String(compact)
|
|
}
|
|
if compact {
|
|
return p.Key + ":" + p.Val
|
|
} else {
|
|
return p.Key + ": " + p.Val
|
|
}
|
|
}
|
|
|
|
type Function struct {
|
|
Name string
|
|
Not bool
|
|
Params []*Param
|
|
}
|
|
|
|
func (f *Function) String(compact bool) string {
|
|
var builder strings.Builder
|
|
if f.Not {
|
|
builder.WriteString("!")
|
|
}
|
|
builder.WriteString(f.Name + "(")
|
|
var strParamList []string
|
|
for _, p := range f.Params {
|
|
strParamList = append(strParamList, p.String(compact))
|
|
}
|
|
if compact {
|
|
builder.WriteString(strings.Join(strParamList, ","))
|
|
} else {
|
|
builder.WriteString(strings.Join(strParamList, ", "))
|
|
}
|
|
builder.WriteString(")")
|
|
return builder.String()
|
|
}
|
|
|
|
type paramAndFunctions struct {
|
|
Key string
|
|
AndFunctions []*Function
|
|
}
|
|
|
|
func (p *paramAndFunctions) String(compact bool) string {
|
|
var builder strings.Builder
|
|
if compact {
|
|
builder.WriteString(p.Key + ":")
|
|
} else {
|
|
builder.WriteString(p.Key + ": ")
|
|
}
|
|
var strFunctionList []string
|
|
for _, f := range p.AndFunctions {
|
|
strFunctionList = append(strFunctionList, f.String(compact))
|
|
}
|
|
if compact {
|
|
builder.WriteString(strings.Join(strFunctionList, "&&"))
|
|
} else {
|
|
builder.WriteString(strings.Join(strFunctionList, " && "))
|
|
}
|
|
return builder.String()
|
|
}
|
|
|
|
type RoutingRule struct {
|
|
AndFunctions []*Function
|
|
Outbound string
|
|
}
|
|
|
|
func (r *RoutingRule) String(calcN bool) string {
|
|
var builder strings.Builder
|
|
var n int
|
|
for i, f := range r.AndFunctions {
|
|
if i != 0 {
|
|
builder.WriteString(" && ")
|
|
}
|
|
var paramBuilder strings.Builder
|
|
n += len(f.Params)
|
|
if calcN {
|
|
paramBuilder.WriteString("[n = " + strconv.Itoa(n) + "]")
|
|
} else {
|
|
for j, param := range f.Params {
|
|
if j != 0 {
|
|
paramBuilder.WriteString(", ")
|
|
}
|
|
paramBuilder.WriteString(param.String(false))
|
|
}
|
|
}
|
|
symNot := ""
|
|
if f.Not {
|
|
symNot = "!"
|
|
}
|
|
builder.WriteString(fmt.Sprintf("%v%v(%v)", symNot, f.Name, paramBuilder.String()))
|
|
}
|
|
builder.WriteString(" -> " + r.Outbound)
|
|
return builder.String()
|
|
}
|