package builderimp import ( "github.com/tech/sendico/pkg/db/repository/builder" "go.mongodb.org/mongo-driver/bson" ) type aliasImp struct { lhs builder.Field rhs any } func (a *aliasImp) Field() builder.Field { return a.lhs } func (a *aliasImp) Build() bson.D { return bson.D{{Key: a.lhs.Build(), Value: a.rhs}} } // 1. Null alias (_id: null) func NewNullAlias(lhs builder.Field) builder.Alias { return &aliasImp{lhs: lhs, rhs: nil} } func NewAlias(lhs builder.Field, rhs any) builder.Alias { return &aliasImp{lhs: lhs, rhs: rhs} } // 2. Simple alias (_id: "$taskRef") func NewSimpleAlias(lhs, rhs builder.Field) builder.Alias { return &aliasImp{lhs: lhs, rhs: rhs.Build()} } // 3. Complex alias (_id: { aliasName: "$originalField", ... }) type ComplexAlias struct { lhs builder.Field rhs []builder.Alias // Correcting handling of slice of aliases } func (a *ComplexAlias) Field() builder.Field { return a.lhs } func (a *ComplexAlias) Build() bson.D { fieldMap := bson.M{} for _, alias := range a.rhs { // Each alias.Build() still returns a bson.D aliasDoc := alias.Build() // 1. Marshal the ordered D into raw BSON bytes raw, err := bson.Marshal(aliasDoc) if err != nil { panic("Failed to marshal alias document: " + err.Error()) } // 2. Unmarshal those bytes into an unordered M var docM bson.M if err := bson.Unmarshal(raw, &docM); err != nil { panic("Failed to unmarshal alias document: " + err.Error()) } // Merge into our accumulator for k, v := range docM { fieldMap[k] = v } } return bson.D{{Key: a.lhs.Build(), Value: fieldMap}} } func NewComplexAlias(lhs builder.Field, rhs []builder.Alias) builder.Alias { return &ComplexAlias{lhs: lhs, rhs: rhs} } type aliasesImp struct { aliases []builder.Alias } func (a *aliasesImp) Field() builder.Field { if len(a.aliases) > 0 { return a.aliases[0].Field() } return NewFieldImp("") } func (a *aliasesImp) Build() bson.D { results := make([]bson.D, 0) for _, alias := range a.aliases { results = append(results, alias.Build()) } aliases := bson.D{} for _, r := range results { aliases = append(aliases, r...) } return aliases } func NewAliases(aliases ...builder.Alias) builder.Alias { return &aliasesImp{aliases: aliases} }