From 8df0984b86bec85281eda0f5f0b5be5a5b8348ca Mon Sep 17 00:00:00 2001
From: royalcat <k.adamovich20@gmail.com>
Date: Fri, 4 Apr 2025 02:29:10 +0400
Subject: [PATCH] graphq fs interface

---
 server/.gqlgen.yml                            |  1 +
 .../graphql/{model/entry.go => fs/entries.go} | 17 +++---
 server/src/delivery/graphql/fs/plain.go       | 42 ++++++++++++++
 server/src/delivery/graphql/fs/resolver.go    | 30 ++++++++++
 server/src/delivery/graphql/generated.go      | 47 +++++++--------
 .../src/delivery/graphql/model/models_gen.go  | 58 -------------------
 .../delivery/graphql/resolver/fs.resolvers.go |  5 +-
 .../graphql/resolver/query.resolvers.go       |  3 +-
 8 files changed, 111 insertions(+), 92 deletions(-)
 rename server/src/delivery/graphql/{model/entry.go => fs/entries.go} (81%)
 create mode 100644 server/src/delivery/graphql/fs/plain.go
 create mode 100644 server/src/delivery/graphql/fs/resolver.go

diff --git a/server/.gqlgen.yml b/server/.gqlgen.yml
index 349a706..896f135 100644
--- a/server/.gqlgen.yml
+++ b/server/.gqlgen.yml
@@ -45,3 +45,4 @@ models:
 
 autobind:
   - "git.kmsign.ru/royalcat/tstor/server/src/delivery/filter"
+  - "git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/fs"
diff --git a/server/src/delivery/graphql/model/entry.go b/server/src/delivery/graphql/fs/entries.go
similarity index 81%
rename from server/src/delivery/graphql/model/entry.go
rename to server/src/delivery/graphql/fs/entries.go
index 0c38b85..2cb5076 100644
--- a/server/src/delivery/graphql/model/entry.go
+++ b/server/src/delivery/graphql/fs/entries.go
@@ -1,8 +1,9 @@
-package model
+package fs
 
 import (
 	"context"
 
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
 	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
 )
 
@@ -11,7 +12,7 @@ type FsElem interface {
 	IsDir() bool
 }
 
-func FillFsEntry(ctx context.Context, e FsElem, fs vfs.Filesystem, path string) (FsEntry, error) {
+func FillFsEntry(ctx context.Context, e FsElem, fs vfs.Filesystem, path string) (model.FsEntry, error) {
 	switch e.(type) {
 	case *vfs.ResolverFS:
 		e := e.(*vfs.ResolverFS)
@@ -53,12 +54,12 @@ func FillFsEntry(ctx context.Context, e FsElem, fs vfs.Filesystem, path string)
 	}
 }
 
-func ReadEntries(ctx context.Context, fs vfs.Filesystem, path string) ([]FsEntry, error) {
+func ReadEntries(ctx context.Context, fs vfs.Filesystem, path string) ([]model.FsEntry, error) {
 	entries, err := fs.ReadDir(ctx, path)
 	if err != nil {
 		return nil, err
 	}
-	out := []FsEntry{}
+	out := []model.FsEntry{}
 	for _, e := range entries {
 		entry, err := FillFsEntry(ctx, e, fs, ".")
 		if err != nil {
@@ -69,12 +70,12 @@ func ReadEntries(ctx context.Context, fs vfs.Filesystem, path string) ([]FsEntry
 	return out, nil
 }
 
-func (obj *ResolverFs) ResolverEntries(ctx context.Context) ([]FsEntry, error) {
+func (obj *ResolverFs) ResolverEntries(ctx context.Context) ([]model.FsEntry, error) {
 	entries, err := obj.FS.ReadDir(ctx, ".")
 	if err != nil {
 		return nil, err
 	}
-	out := []FsEntry{}
+	out := []model.FsEntry{}
 	for _, e := range entries {
 		entry, err := FillFsEntry(ctx, e, obj.FS, ".")
 		if err != nil {
@@ -85,12 +86,12 @@ func (obj *ResolverFs) ResolverEntries(ctx context.Context) ([]FsEntry, error) {
 	return out, nil
 }
 
-func (obj *SimpleDir) SimpleDirEntries(ctx context.Context) ([]FsEntry, error) {
+func (obj *SimpleDir) SimpleDirEntries(ctx context.Context) ([]model.FsEntry, error) {
 	entries, err := obj.FS.ReadDir(ctx, obj.Path)
 	if err != nil {
 		return nil, err
 	}
-	out := []FsEntry{}
+	out := []model.FsEntry{}
 	for _, e := range entries {
 		entry, err := FillFsEntry(ctx, e, obj.FS, obj.Path)
 		if err != nil {
diff --git a/server/src/delivery/graphql/fs/plain.go b/server/src/delivery/graphql/fs/plain.go
new file mode 100644
index 0000000..98e7726
--- /dev/null
+++ b/server/src/delivery/graphql/fs/plain.go
@@ -0,0 +1,42 @@
+package fs
+
+import (
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
+	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
+)
+
+var _ model.FsEntry = (*SimpleDir)(nil)
+var _ model.Dir = (*SimpleDir)(nil)
+
+type SimpleDir struct {
+	Name    string          `json:"name"`
+	Entries []model.FsEntry `json:"entries"`
+	FS      vfs.Filesystem  `json:"-"`
+	Path    string          `json:"-"`
+}
+
+func (SimpleDir) IsDir()               {}
+func (this SimpleDir) GetName() string { return this.Name }
+func (this SimpleDir) GetEntries() []model.FsEntry {
+	if this.Entries == nil {
+		return nil
+	}
+	interfaceSlice := make([]model.FsEntry, 0, len(this.Entries))
+	for _, concrete := range this.Entries {
+		interfaceSlice = append(interfaceSlice, concrete)
+	}
+	return interfaceSlice
+}
+
+func (SimpleDir) IsFsEntry() {}
+
+type SimpleFile struct {
+	Name string `json:"name"`
+	Size int64  `json:"size"`
+}
+
+func (SimpleFile) IsFile()              {}
+func (this SimpleFile) GetName() string { return this.Name }
+func (this SimpleFile) GetSize() int64  { return this.Size }
+
+func (SimpleFile) IsFsEntry() {}
diff --git a/server/src/delivery/graphql/fs/resolver.go b/server/src/delivery/graphql/fs/resolver.go
new file mode 100644
index 0000000..b999778
--- /dev/null
+++ b/server/src/delivery/graphql/fs/resolver.go
@@ -0,0 +1,30 @@
+package fs
+
+import (
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
+	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
+)
+
+var _ model.FsEntry = (*ResolverFs)(nil)
+var _ model.Dir = (*ResolverFs)(nil)
+
+type ResolverFs struct {
+	Name    string          `json:"name"`
+	Entries []model.FsEntry `json:"entries"`
+	FS      *vfs.ResolverFS `json:"-"`
+}
+
+func (ResolverFs) IsDir()               {}
+func (this ResolverFs) GetName() string { return this.Name }
+func (this ResolverFs) GetEntries() []model.FsEntry {
+	if this.Entries == nil {
+		return nil
+	}
+	interfaceSlice := make([]model.FsEntry, 0, len(this.Entries))
+	for _, concrete := range this.Entries {
+		interfaceSlice = append(interfaceSlice, concrete)
+	}
+	return interfaceSlice
+}
+
+func (ResolverFs) IsFsEntry() {}
diff --git a/server/src/delivery/graphql/generated.go b/server/src/delivery/graphql/generated.go
index c90add6..a83d077 100644
--- a/server/src/delivery/graphql/generated.go
+++ b/server/src/delivery/graphql/generated.go
@@ -14,6 +14,7 @@ import (
 	"time"
 
 	"git.kmsign.ru/royalcat/tstor/server/src/delivery/filter"
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/fs"
 	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
 	"github.com/99designs/gqlgen/graphql"
 	"github.com/99designs/gqlgen/graphql/introspection"
@@ -107,10 +108,10 @@ type QueryResolver interface {
 	FsEntry(ctx context.Context, path string) (model.FsEntry, error)
 }
 type ResolverFSResolver interface {
-	Entries(ctx context.Context, obj *model.ResolverFs) ([]model.FsEntry, error)
+	Entries(ctx context.Context, obj *fs.ResolverFs) ([]model.FsEntry, error)
 }
 type SimpleDirResolver interface {
-	Entries(ctx context.Context, obj *model.SimpleDir) ([]model.FsEntry, error)
+	Entries(ctx context.Context, obj *fs.SimpleDir) ([]model.FsEntry, error)
 }
 type SubscriptionResolver interface {
 	TaskProgress(ctx context.Context, taskID string) (<-chan model.Progress, error)
@@ -1178,7 +1179,7 @@ func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field
 	return fc, nil
 }
 
-func (ec *executionContext) _ResolverFS_name(ctx context.Context, field graphql.CollectedField, obj *model.ResolverFs) (ret graphql.Marshaler) {
+func (ec *executionContext) _ResolverFS_name(ctx context.Context, field graphql.CollectedField, obj *fs.ResolverFs) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_ResolverFS_name(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -1222,7 +1223,7 @@ func (ec *executionContext) fieldContext_ResolverFS_name(_ context.Context, fiel
 	return fc, nil
 }
 
-func (ec *executionContext) _ResolverFS_entries(ctx context.Context, field graphql.CollectedField, obj *model.ResolverFs) (ret graphql.Marshaler) {
+func (ec *executionContext) _ResolverFS_entries(ctx context.Context, field graphql.CollectedField, obj *fs.ResolverFs) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_ResolverFS_entries(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -1364,7 +1365,7 @@ func (ec *executionContext) fieldContext_Schema_mutation(_ context.Context, fiel
 	return fc, nil
 }
 
-func (ec *executionContext) _SimpleDir_name(ctx context.Context, field graphql.CollectedField, obj *model.SimpleDir) (ret graphql.Marshaler) {
+func (ec *executionContext) _SimpleDir_name(ctx context.Context, field graphql.CollectedField, obj *fs.SimpleDir) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_SimpleDir_name(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -1408,7 +1409,7 @@ func (ec *executionContext) fieldContext_SimpleDir_name(_ context.Context, field
 	return fc, nil
 }
 
-func (ec *executionContext) _SimpleDir_entries(ctx context.Context, field graphql.CollectedField, obj *model.SimpleDir) (ret graphql.Marshaler) {
+func (ec *executionContext) _SimpleDir_entries(ctx context.Context, field graphql.CollectedField, obj *fs.SimpleDir) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_SimpleDir_entries(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -1474,7 +1475,7 @@ func (ec *executionContext) fieldContext_SimpleDir_entries(_ context.Context, fi
 	return fc, nil
 }
 
-func (ec *executionContext) _SimpleFile_name(ctx context.Context, field graphql.CollectedField, obj *model.SimpleFile) (ret graphql.Marshaler) {
+func (ec *executionContext) _SimpleFile_name(ctx context.Context, field graphql.CollectedField, obj *fs.SimpleFile) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_SimpleFile_name(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -1518,7 +1519,7 @@ func (ec *executionContext) fieldContext_SimpleFile_name(_ context.Context, fiel
 	return fc, nil
 }
 
-func (ec *executionContext) _SimpleFile_size(ctx context.Context, field graphql.CollectedField, obj *model.SimpleFile) (ret graphql.Marshaler) {
+func (ec *executionContext) _SimpleFile_size(ctx context.Context, field graphql.CollectedField, obj *fs.SimpleFile) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_SimpleFile_size(ctx, field)
 	if err != nil {
 		return graphql.Null
@@ -3850,16 +3851,16 @@ func (ec *executionContext) _Dir(ctx context.Context, sel ast.SelectionSet, obj
 	switch obj := (obj).(type) {
 	case nil:
 		return graphql.Null
-	case model.SimpleDir:
+	case fs.SimpleDir:
 		return ec._SimpleDir(ctx, sel, &obj)
-	case *model.SimpleDir:
+	case *fs.SimpleDir:
 		if obj == nil {
 			return graphql.Null
 		}
 		return ec._SimpleDir(ctx, sel, obj)
-	case model.ResolverFs:
+	case fs.ResolverFs:
 		return ec._ResolverFS(ctx, sel, &obj)
-	case *model.ResolverFs:
+	case *fs.ResolverFs:
 		if obj == nil {
 			return graphql.Null
 		}
@@ -3873,9 +3874,9 @@ func (ec *executionContext) _File(ctx context.Context, sel ast.SelectionSet, obj
 	switch obj := (obj).(type) {
 	case nil:
 		return graphql.Null
-	case model.SimpleFile:
+	case fs.SimpleFile:
 		return ec._SimpleFile(ctx, sel, &obj)
-	case *model.SimpleFile:
+	case *fs.SimpleFile:
 		if obj == nil {
 			return graphql.Null
 		}
@@ -3889,23 +3890,23 @@ func (ec *executionContext) _FsEntry(ctx context.Context, sel ast.SelectionSet,
 	switch obj := (obj).(type) {
 	case nil:
 		return graphql.Null
-	case model.SimpleFile:
+	case fs.SimpleFile:
 		return ec._SimpleFile(ctx, sel, &obj)
-	case *model.SimpleFile:
+	case *fs.SimpleFile:
 		if obj == nil {
 			return graphql.Null
 		}
 		return ec._SimpleFile(ctx, sel, obj)
-	case model.SimpleDir:
+	case fs.SimpleDir:
 		return ec._SimpleDir(ctx, sel, &obj)
-	case *model.SimpleDir:
+	case *fs.SimpleDir:
 		if obj == nil {
 			return graphql.Null
 		}
 		return ec._SimpleDir(ctx, sel, obj)
-	case model.ResolverFs:
+	case fs.ResolverFs:
 		return ec._ResolverFS(ctx, sel, &obj)
-	case *model.ResolverFs:
+	case *fs.ResolverFs:
 		if obj == nil {
 			return graphql.Null
 		}
@@ -4128,7 +4129,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
 
 var resolverFSImplementors = []string{"ResolverFS", "Dir", "FsEntry"}
 
-func (ec *executionContext) _ResolverFS(ctx context.Context, sel ast.SelectionSet, obj *model.ResolverFs) graphql.Marshaler {
+func (ec *executionContext) _ResolverFS(ctx context.Context, sel ast.SelectionSet, obj *fs.ResolverFs) graphql.Marshaler {
 	fields := graphql.CollectFields(ec.OperationContext, sel, resolverFSImplementors)
 
 	out := graphql.NewFieldSet(fields)
@@ -4241,7 +4242,7 @@ func (ec *executionContext) _Schema(ctx context.Context, sel ast.SelectionSet, o
 
 var simpleDirImplementors = []string{"SimpleDir", "Dir", "FsEntry"}
 
-func (ec *executionContext) _SimpleDir(ctx context.Context, sel ast.SelectionSet, obj *model.SimpleDir) graphql.Marshaler {
+func (ec *executionContext) _SimpleDir(ctx context.Context, sel ast.SelectionSet, obj *fs.SimpleDir) graphql.Marshaler {
 	fields := graphql.CollectFields(ec.OperationContext, sel, simpleDirImplementors)
 
 	out := graphql.NewFieldSet(fields)
@@ -4316,7 +4317,7 @@ func (ec *executionContext) _SimpleDir(ctx context.Context, sel ast.SelectionSet
 
 var simpleFileImplementors = []string{"SimpleFile", "File", "FsEntry"}
 
-func (ec *executionContext) _SimpleFile(ctx context.Context, sel ast.SelectionSet, obj *model.SimpleFile) graphql.Marshaler {
+func (ec *executionContext) _SimpleFile(ctx context.Context, sel ast.SelectionSet, obj *fs.SimpleFile) graphql.Marshaler {
 	fields := graphql.CollectFields(ec.OperationContext, sel, simpleFileImplementors)
 
 	out := graphql.NewFieldSet(fields)
diff --git a/server/src/delivery/graphql/model/models_gen.go b/server/src/delivery/graphql/model/models_gen.go
index 293b1f8..2891015 100644
--- a/server/src/delivery/graphql/model/models_gen.go
+++ b/server/src/delivery/graphql/model/models_gen.go
@@ -2,10 +2,6 @@
 
 package model
 
-import (
-	"git.kmsign.ru/royalcat/tstor/server/src/vfs"
-)
-
 type Dir interface {
 	IsFsEntry()
 	IsDir()
@@ -47,65 +43,11 @@ type Plugin struct {
 type Query struct {
 }
 
-type ResolverFs struct {
-	Name    string          `json:"name"`
-	Entries []FsEntry       `json:"entries"`
-	FS      *vfs.ResolverFS `json:"-"`
-}
-
-func (ResolverFs) IsDir()               {}
-func (this ResolverFs) GetName() string { return this.Name }
-func (this ResolverFs) GetEntries() []FsEntry {
-	if this.Entries == nil {
-		return nil
-	}
-	interfaceSlice := make([]FsEntry, 0, len(this.Entries))
-	for _, concrete := range this.Entries {
-		interfaceSlice = append(interfaceSlice, concrete)
-	}
-	return interfaceSlice
-}
-
-func (ResolverFs) IsFsEntry() {}
-
 type Schema struct {
 	Query    *Query    `json:"query,omitempty"`
 	Mutation *Mutation `json:"mutation,omitempty"`
 }
 
-type SimpleDir struct {
-	Name    string         `json:"name"`
-	Entries []FsEntry      `json:"entries"`
-	FS      vfs.Filesystem `json:"-"`
-	Path    string         `json:"-"`
-}
-
-func (SimpleDir) IsDir()               {}
-func (this SimpleDir) GetName() string { return this.Name }
-func (this SimpleDir) GetEntries() []FsEntry {
-	if this.Entries == nil {
-		return nil
-	}
-	interfaceSlice := make([]FsEntry, 0, len(this.Entries))
-	for _, concrete := range this.Entries {
-		interfaceSlice = append(interfaceSlice, concrete)
-	}
-	return interfaceSlice
-}
-
-func (SimpleDir) IsFsEntry() {}
-
-type SimpleFile struct {
-	Name string `json:"name"`
-	Size int64  `json:"size"`
-}
-
-func (SimpleFile) IsFile()              {}
-func (this SimpleFile) GetName() string { return this.Name }
-func (this SimpleFile) GetSize() int64  { return this.Size }
-
-func (SimpleFile) IsFsEntry() {}
-
 type Subscription struct {
 }
 
diff --git a/server/src/delivery/graphql/resolver/fs.resolvers.go b/server/src/delivery/graphql/resolver/fs.resolvers.go
index 8060b33..831094d 100644
--- a/server/src/delivery/graphql/resolver/fs.resolvers.go
+++ b/server/src/delivery/graphql/resolver/fs.resolvers.go
@@ -8,16 +8,17 @@ import (
 	"context"
 
 	graph "git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql"
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/fs"
 	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
 )
 
 // Entries is the resolver for the entries field.
-func (r *resolverFSResolver) Entries(ctx context.Context, obj *model.ResolverFs) ([]model.FsEntry, error) {
+func (r *resolverFSResolver) Entries(ctx context.Context, obj *fs.ResolverFs) ([]model.FsEntry, error) {
 	return obj.ResolverEntries(ctx)
 }
 
 // Entries is the resolver for the entries field.
-func (r *simpleDirResolver) Entries(ctx context.Context, obj *model.SimpleDir) ([]model.FsEntry, error) {
+func (r *simpleDirResolver) Entries(ctx context.Context, obj *fs.SimpleDir) ([]model.FsEntry, error) {
 	return obj.SimpleDirEntries(ctx)
 }
 
diff --git a/server/src/delivery/graphql/resolver/query.resolvers.go b/server/src/delivery/graphql/resolver/query.resolvers.go
index 21bba95..88d7508 100644
--- a/server/src/delivery/graphql/resolver/query.resolvers.go
+++ b/server/src/delivery/graphql/resolver/query.resolvers.go
@@ -9,6 +9,7 @@ import (
 	"fmt"
 
 	graph "git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql"
+	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/fs"
 	"git.kmsign.ru/royalcat/tstor/server/src/delivery/graphql/model"
 )
 
@@ -24,7 +25,7 @@ func (r *queryResolver) FsEntry(ctx context.Context, path string) (model.FsEntry
 		return nil, err
 	}
 
-	return model.FillFsEntry(ctx, entry, r.VFS, path)
+	return fs.FillFsEntry(ctx, entry, r.VFS, path)
 }
 
 // Query returns graph.QueryResolver implementation.