Добавить метод во вложенную экспортируемую структуру - PullRequest
0 голосов
/ 02 ноября 2018

Я хотел бы добавить метод во вложенную экспортируемую структуру, который используется в экспортированной структуре.

У меня есть []*ldap.Entry тип, возвращаемый ldap.Search (). Записи

ldap.Entry тип состоит из Attributes []*EntryAttribute. Моя цель - добавить дополнительный метод в ldap.EntryAttribute, например, MarshalJSON

Я могу добавить дополнительный код прямо в пакет ldap, и он будет работать, как я ожидаю. Но это грязный путь:

// EntryAttribute holds a single attribute
type newEntryAttribute struct {
        // Name is the name of the attribute
        Name string
        // Values contain the string values of the attribute
        Values []string
        // ByteValues contain the raw values of the attribute
        ByteValues [][]byte
}

// Print outputs a human-readable description
func (e EntryAttribute) MarshalJSON() ([]byte, error) {
        b := newEntryAttribute(e)
        b.ByteValues = nil
        return json.Marshal(b)
}

Как я могу сделать это более элегантно?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Пока что я нашел решение ниже. Это не элегантно, но не требует модификации пакета.

type myEntry struct {
        *ldap.Entry
        Attributes []*myEntryAttribute
}

type myEntryAttribute struct {
        *ldap.EntryAttribute
}

func (a *myEntryAttribute) MarshalJSON() ([]byte, error) {
        return json.Marshal(struct {
                Name   string
                Values []string 
        }{Name: a.Name, Values: a.Values})
}

func ldapEntry2myEntry(t interface{}) interface{} {
        switch e := t.(type) {
        case []*ldap.Entry:
                var res []interface{}
                for _, v := range e {
                        res = append(res, ldapEntry2myEntry(v))
                }
                return res
        case *ldap.Entry:
                var att []*myEntryAttribute
                for _, a := range e.Attributes {
                        att = append(att, &myEntryAttribute{a})
                }
                return &myEntry{e, att}
        }
        return nil
}

... ... ...

data, err := json.Marshal(ldapEntry2myEntry(sr.Entries))
if err != nil {
        log.Fatal("error")
}
fmt.Printf("%s\n", data)

// or only one element

data, err := json.Marshal(ldapEntry2myEntry(sr.Entries[0]))
if err != nil {
        log.Fatal("error")
}
fmt.Printf("%s\n", data)
0 голосов
/ 02 ноября 2018

Самое близкое, что вы можете придумать, - это создать метод по вашему собственному типу, который встраивает тип EntryAttribute. Примерно так:

package mine

import "github.com/go-ldap/ldap""

type EntryAttribute {
    ldap.EntryAttribute
}

func (e EntryAttribute) MarshalJSON() ([]byte, error) {
    // ...
}

Но тогда вы должны использовать ваш тип, а не исходный тип, везде в вашей программе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...