Skip to content

Commit

Permalink
feat(resolv): refactored the Context JSON format serialization st…
Browse files Browse the repository at this point in the history
…ructure to simplify serialization/deserialization operations, making the serialization structure more universal and unified.

BREAKING CHANGE: Changed the serialization structure of the `Context` `JSON` format, as well as the new functions for the `Directive` and `Comment` context objects.

The `Context` `JSON` format serialization structure changes as follows:

Before:

```json
{
    "main-config": "C:\\test\\test.conf",
    "configs":
    {
        "C:\\test\\test.conf":
        [
            {
                "http":
                {
                    "params":
                    [
                        {
                            "inline": true, "comments": "test comment"
                        },
                        {
                            "server":
                            {
                                "params":
                                [
                                    {
                                        "directive": "server_name", "params": "testserver"
                                    },
                                    {
                                        "location": {"value": "~ /test"}
                                    },
                                    {
                                        "include":
                                        {
                                            "value": "conf.d\\include*conf",
                                            "params": ["conf.d\\include.location1.conf", "conf.d\\include.location2.conf"]
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ],
        "conf.d\\include.location1.conf":
        [
            {
                "location": {"value": "~ /test1"}
            }
        ],
        "conf.d\\include.location2.conf":
        [
            {
                "location": {"value": "^~ /test2"}
            }
        ]
    }
}
```

After:

```json
{
    "main-config": "C:\\test\\test.conf",
    "configs":
    {
        "C:\\test\\test.conf":
        {
            "context-type": "config",
            "value": "C:\\test\\test.conf",
            "params":
            [
                {
                    "context-type": "http",
                    "params":
                    [
                        {
                            "context-type": "inline_comment", "value": "test comment"
                        },
                        {
                            "context-type": "server",
                            "params":
                            [
                                {
                                    "context-type": "directive", "value": "server_name testserver"
                                },
                                {
                                    "context-type": "location", "value": "~ /test"
                                },
                                {
                                    "context-type": "include",
                                    "value": "conf.d\\include*conf",
                                    "params": ["conf.d\\include.location1.conf", "conf.d\\include.location2.conf"]
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        "conf.d\\include.location1.conf":
        {
            "context-type": "config",
            "value": "conf.d\\include.location1.conf",
            "params":
            [
                {
                    "context-type": "location", "value": "~ /test1"
                }
            ]
        },
        "conf.d\\include.location2.conf":
        {
            "context-type": "config",
            "value": "conf.d\\include.location2.conf",
            "params":
            [
                {
                    "context-type": "location", "value": "^~ /test2"
                }
            ]
        }
    }
}
```

The code migration example for creating function calls for `Directive` and `Comment` context objects is as follows:

Before:

```go
import (
	"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
)

// new directive context
newDirective := local.NewDirective("some_directive", "some params")
// new comment context
newComment := local.NewComment("some comments", false)
newComment := local.NewComment("some inline comments", true)
```

After:

```go
import (
	"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
	"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"
)

// new directive context
newDirective := local.NewContext(context_type.TypeDirective, "some_directive some params")
// new comment context
newComment := local.NewContext(context_type.TypeComment, "some comments")
newInlineComment := local.NewContext(context_type.TypeInlineComment, "some inline comments")
```
  • Loading branch information
ClessLi committed Apr 23, 2024
1 parent 669a509 commit 4c0dcaf
Show file tree
Hide file tree
Showing 20 changed files with 592 additions and 1,735 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ package main

import (
"fmt"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"

"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context"
Expand All @@ -286,7 +287,7 @@ func main() {
QueryByKeyWords(context.NewKeyWords(context_type.TypeIf).SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`)).Target().
QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetStringMatchingValue("proxy_pass")).Position()
// insert an inline comment after the "proxy_pass" `directive` context
err = ctx.Insert(local.NewComment(fmt.Sprintf("[%s]test comments", time.Now().String()), true), idx+1).Error()
err = ctx.Insert(local.NewContext(context_type.TypeInlineComment, fmt.Sprintf("[%s]test comments", time.Now().String())), idx+1).Error()
if err != nil {
panic(err)
}
Expand All @@ -308,9 +309,10 @@ func main() {
// new main context
newMainContext, err := local.NewMain("/usr/local/nginx/conf/nginx.conf")
// new directive context
newDirective := local.NewDirective("some_directive", "some params")
newDirective := local.NewContext(context_type.TypeDirective, "some_directive some params")
// new comment context
newComment := local.NewComment("some comments", false)
newComment := local.NewContext(context_type.TypeComment, "some comments")
newInlineComment := local.NewContext(context_type.TypeInlineComment, "some inline comments")
// new other context
newConfig := local.NewContext(context_type.TypeConfig, "conf.d/location.conf")
newInclude := local.NewContext(context_type.TypeInclude, "conf.d/*.conf")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
const INDENT = " "

type BasicContext struct {
ContextType context_type.ContextType `json:"-"`
ContextType context_type.ContextType `json:"context-type"`
ContextValue string `json:"value,omitempty"`
Children []context.Context `json:"params,omitempty"`

Expand Down
146 changes: 73 additions & 73 deletions pkg/resolv/V3/nginx/configuration/context/local/basic_context_test.go

Large diffs are not rendered by default.

44 changes: 33 additions & 11 deletions pkg/resolv/V3/nginx/configuration/context/local/comment.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package local

import (
"encoding/json"
"github.com/ClessLi/bifrost/internal/pkg/code"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"
Expand All @@ -9,12 +10,22 @@ import (
)

type Comment struct {
Comments string `json:"comments"`
Inline bool `json:"inline,omitempty"`
Comments string
Inline bool

fatherContext context.Context
}

func (c *Comment) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
ContextType context_type.ContextType `json:"context-type"`
Value string `json:"value"`
}{
ContextType: c.Type(),
Value: c.Value(),
})
}

func (c *Comment) Insert(ctx context.Context, idx int) context.Context {
return context.ErrContext(errors.WithCode(code.ErrV3InvalidOperation, "comment cannot insert context"))
}
Expand Down Expand Up @@ -91,22 +102,33 @@ func (c *Comment) ConfigLines(isDumping bool) ([]string, error) {
return []string{"# " + c.Value()}, nil
}

func NewComment(comments string, isInline bool) *Comment {
return &Comment{
Comments: comments,
Inline: isInline,
fatherContext: context.NullContext(),
func registerCommentBuilder() error {
builderMap[context_type.TypeComment] = func(value string) context.Context {
return &Comment{
Comments: value,
Inline: false,
fatherContext: context.NullContext(),
}
}
builderMap[context_type.TypeInlineComment] = func(value string) context.Context {
return &Comment{
Comments: value,
Inline: true,
fatherContext: context.NullContext(),
}
}
return nil
}

func registerCommentParseFunc() error {
inStackParseFuncMap[context_type.TypeComment] = func(data []byte, idx *int) context.Context {
if subMatch := RegCommentHead.FindSubmatch(data[*idx:]); len(subMatch) == 3 { //nolint:nestif
matchIndexes := RegCommentHead.FindIndex(data[*idx:])
cmt := NewComment(
string(subMatch[2]),
!RegLineBreak.Match(subMatch[1]) && *idx != 0,
)
ct := context_type.TypeComment
if !RegLineBreak.Match(subMatch[1]) && *idx != 0 {
ct = context_type.TypeInlineComment
}
cmt := NewContext(ct, string(subMatch[2]))
*idx += matchIndexes[len(matchIndexes)-1] - 1

return cmt
Expand Down
56 changes: 0 additions & 56 deletions pkg/resolv/V3/nginx/configuration/context/local/comment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,62 +575,6 @@ func TestComment_Value(t *testing.T) {
}
}

func TestNewComment(t *testing.T) {
type args struct {
comments string
isInline bool
}
tests := []struct {
name string
args args
want *Comment
}{
{
name: "null value comment",
args: args{
comments: "",
isInline: false,
},
want: &Comment{
Comments: "",
Inline: false,
fatherContext: context.NullContext(),
},
},
{
name: "some only space comment",
args: args{
comments: " \t ",
isInline: true,
},
want: &Comment{
Comments: " \t ",
Inline: true,
fatherContext: context.NullContext(),
},
},
{
name: "normal comment",
args: args{
comments: " test comment",
isInline: true,
},
want: &Comment{
Comments: " test comment",
Inline: true,
fatherContext: context.NullContext(),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewComment(tt.args.comments, tt.args.isInline); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewComment() = %v, want %v", got, tt.want)
}
})
}
}

func Test_registerCommentParseFunc(t *testing.T) {
tests := []struct {
name string
Expand Down
7 changes: 1 addition & 6 deletions pkg/resolv/V3/nginx/configuration/context/local/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package local

import (
"encoding/json"
"github.com/ClessLi/bifrost/internal/pkg/code"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"
Expand All @@ -13,11 +12,7 @@ import (

type Config struct {
BasicContext
context.ConfigPath
}

func (c *Config) MarshalJSON() ([]byte, error) {
return json.Marshal(c.BasicContext.Children)
context.ConfigPath `json:"-"`
}

func (c *Config) isInGraph() bool {
Expand Down
Loading

0 comments on commit 4c0dcaf

Please sign in to comment.