diff options
| author | Shulhan <ms@kilabit.info> | 2021-06-03 08:15:00 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-06-03 08:15:00 +0700 |
| commit | f16f0c87bc6ed4d912528710eef4473b86064153 (patch) | |
| tree | b98bf3ac6016c15856d7eec34b7e4fe0014a02bc /lib | |
| parent | 72d3515006e58d842fb76c5f3d49bb5aaff02e65 (diff) | |
| download | pakakeh.go-f16f0c87bc6ed4d912528710eef4473b86064153.tar.xz | |
memfs: add function to Merge one or more instance of MemFS
The Merge function merge one or more instance of MemFS into single MemFS
instance.
If there are two instance of Node that have the same path, the last
instance will be ignored.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/memfs/memfs.go | 49 | ||||
| -rw-r--r-- | lib/memfs/memfs_test.go | 74 |
2 files changed, 123 insertions, 0 deletions
diff --git a/lib/memfs/memfs.go b/lib/memfs/memfs.go index e62b1ccf..29f6ea09 100644 --- a/lib/memfs/memfs.go +++ b/lib/memfs/memfs.go @@ -44,6 +44,46 @@ type MemFS struct { } // +// Merge one or more instances of MemFS into single hierarchy. +// +// If there are two instance of Node that have the same path, the last +// instance will be ignored. +// +func Merge(params ...*MemFS) (merged *MemFS) { + merged = &MemFS{ + PathNodes: &PathNode{ + v: make(map[string]*Node), + }, + Root: &Node{ + SysPath: "..", + Path: "/", + }, + } + + merged.PathNodes.v["/"] = merged.Root + + for _, mfs := range params { + for _, child := range mfs.Root.Childs { + _, exist := merged.PathNodes.v[child.Path] + if exist { + continue + } + merged.Root.AddChild(child) + } + for path, node := range mfs.PathNodes.v { + if path == "/" { + continue + } + _, exist := merged.PathNodes.v[path] + if !exist { + merged.PathNodes.v[path] = node + } + } + } + return merged +} + +// // New create and initialize new memory file system from directory Root using // list of regular expresssion for Including or Excluding files. // @@ -253,6 +293,15 @@ func (mfs *MemFS) Get(path string) (node *Node, err error) { } // +// MustGet return the Node representation of file in memory by its path if its +// exist or nil the path is not exist. +// +func (mfs *MemFS) MustGet(path string) (node *Node) { + node, _ = mfs.Get(path) + return node +} + +// // Open the named file for reading. // This is an alias to Get() method, to make it implement http.FileSystem. // diff --git a/lib/memfs/memfs_test.go b/lib/memfs/memfs_test.go index fc680401..8a130e42 100644 --- a/lib/memfs/memfs_test.go +++ b/lib/memfs/memfs_test.go @@ -478,3 +478,77 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } + +func TestMerge(t *testing.T) { + optsDirect := &Options{ + Root: "testdata/direct", + } + mfsDirect, err := New(optsDirect) + if err != nil { + t.Fatal(err) + } + + optsInclude := &Options{ + Root: "testdata/include", + } + mfsInclude, err := New(optsInclude) + if err != nil { + t.Fatal(err) + } + + cases := []struct { + desc string + params []*MemFS + exp *MemFS + }{{ + desc: "with the same instance", + params: []*MemFS{mfsDirect, mfsDirect}, + exp: &MemFS{ + PathNodes: &PathNode{ + v: map[string]*Node{ + "/": &Node{ + SysPath: "..", + Path: "/", + Childs: []*Node{ + mfsDirect.MustGet("/add"), + }, + }, + "/add": mfsDirect.MustGet("/add"), + "/add/file": mfsDirect.MustGet("/add/file"), + "/add/file2": mfsDirect.MustGet("/add/file2"), + }, + }, + }, + }, { + desc: "with different instances", + params: []*MemFS{mfsDirect, mfsInclude}, + exp: &MemFS{ + PathNodes: &PathNode{ + v: map[string]*Node{ + "/": &Node{ + SysPath: "..", + Path: "/", + Childs: []*Node{ + mfsDirect.MustGet("/add"), + mfsInclude.MustGet("/index.css"), + mfsInclude.MustGet("/index.html"), + mfsInclude.MustGet("/index.js"), + }, + }, + "/add": mfsDirect.MustGet("/add"), + "/add/file": mfsDirect.MustGet("/add/file"), + "/add/file2": mfsDirect.MustGet("/add/file2"), + "/index.css": mfsInclude.MustGet("/index.css"), + "/index.html": mfsInclude.MustGet("/index.html"), + "/index.js": mfsInclude.MustGet("/index.js"), + }, + }, + }, + }} + + for _, c := range cases { + got := Merge(c.params...) + + test.Assert(t, c.desc, c.exp.PathNodes.v, got.PathNodes.v) + } +} |
