// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package f3 import ( "context" "fmt" "code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/kind" "code.forgejo.org/f3/gof3/v3/options" "code.forgejo.org/f3/gof3/v3/path" objects_helper "code.forgejo.org/f3/gof3/v3/tree/f3/objects" "code.forgejo.org/f3/gof3/v3/tree/generic" ) type treeF3 struct { generic.Tree options options.Interface objectsHelper objects_helper.Interface } type setFunc func(parent path.Path, node generic.NodeInterface) type TreeInterface interface { generic.TreeInterface IsContainer(kind.Kind) bool NewFormat(kind kind.Kind) f3.Interface CreateChild(ctx context.Context, pathString string, set setFunc) GetObjectsHelper() objects_helper.Interface } func (o *treeF3) GetChildrenKind(parentKind kind.Kind) kind.Kind { if childrenKind, ok := childrenKind[parentKind]; ok { return childrenKind } panic(fmt.Errorf("unexpected kind %s", parentKind)) } func (o *treeF3) IsContainer(kind kind.Kind) bool { if isContainer, ok := isContainer[kind]; ok { return isContainer } return false } func (o *treeF3) NewFormat(kind kind.Kind) f3.Interface { return f3.New(string(kind)) } func (o *treeF3) GetObjectsHelper() objects_helper.Interface { return o.objectsHelper } func (o *treeF3) CreateChild(ctx context.Context, pathString string, set setFunc) { p := generic.NewPathFromString(pathString) o.Apply(ctx, p, generic.NewApplyOptions(func(ctx context.Context, parent, p path.Path, node generic.NodeInterface) { o.Trace("%s %s | %T %s", parent.String(), node.GetID(), node, node.GetKind()) child := o.Factory(ctx, o.GetChildrenKind(node.GetKind())) child.SetParent(node) childParentPath := parent.Append(node) if set != nil { set(childParentPath, child) } child.Upsert(ctx) child.List(ctx) })) } func newTreeF3(ctx context.Context, opts options.Interface) generic.TreeInterface { tree := &treeF3{} tree.Init(tree, opts) tree.objectsHelper = objects_helper.NewObjectsHelper() tree.SetDriver(GetForgeFactory(opts.GetName())(tree, opts)) tree.Register(kind.KindRoot, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindForge}) }) tree.Register(KindForge, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindTopics, KindUsers, KindOrganizations}) }) tree.Register(KindUser, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindProjects}) }) tree.Register(KindOrganization, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindProjects}) }) tree.Register(KindProject, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindRepositories, KindLabels, KindMilestones, KindIssues, KindPullRequests, KindReleases}) }) tree.Register(KindIssue, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindComments, KindReactions}) }) tree.Register(KindRepository, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newRepositoryNode(ctx, tree) }) tree.Register(KindPullRequest, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindComments, KindReactions, KindReviews}) }) tree.Register(KindReview, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindReviewComments, KindReactions}) }) tree.Register(KindComment, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindReactions}) }) tree.Register(KindRelease, func(ctx context.Context, k kind.Kind) generic.NodeInterface { return newFixedChildrenNode(ctx, tree, []kind.Kind{KindAssets}) }) root := tree.Factory(ctx, kind.KindRoot) tree.SetRoot(root) return tree } func init() { generic.RegisterFactory("f3", newTreeF3) }