package introspect import ( "encoding/xml" "reflect" "strings" "github.com/godbus/dbus/v5" ) // Introspectable implements org.freedesktop.Introspectable. // // You can create it by converting the XML-formatted introspection data from a // string to an Introspectable or call NewIntrospectable with a Node. Then, // export it as org.freedesktop.Introspectable on you object. type Introspectable string // NewIntrospectable returns an Introspectable that returns the introspection // data that corresponds to the given Node. If n.Interfaces doesn't contain the // data for org.freedesktop.DBus.Introspectable, it is added automatically. func NewIntrospectable(n *Node) Introspectable { found := false for _, v := range n.Interfaces { if v.Name == "org.freedesktop.DBus.Introspectable" { found = true break } } if !found { n.Interfaces = append(n.Interfaces, IntrospectData) } b, err := xml.Marshal(n) if err != nil { panic(err) } return Introspectable(strings.TrimSpace(IntrospectDeclarationString) + string(b)) } // Introspect implements org.freedesktop.Introspectable.Introspect. func (i Introspectable) Introspect() (string, *dbus.Error) { return string(i), nil } // Methods returns the description of the methods of v. This can be used to // create a Node which can be passed to NewIntrospectable. func Methods(v interface{}) []Method { t := reflect.TypeOf(v) ms := make([]Method, 0, t.NumMethod()) for i := 0; i < t.NumMethod(); i++ { if t.Method(i).PkgPath != "" { continue } mt := t.Method(i).Type if mt.NumOut() == 0 || mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) { continue } var m Method m.Name = t.Method(i).Name m.Args = make([]Arg, 0, mt.NumIn()+mt.NumOut()-2) for j := 1; j < mt.NumIn(); j++ { if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() && mt.In(j) != reflect.TypeOf((*dbus.Message)(nil)).Elem() { arg := Arg{"", dbus.SignatureOfType(mt.In(j)).String(), "in"} m.Args = append(m.Args, arg) } } for j := 0; j < mt.NumOut()-1; j++ { arg := Arg{"", dbus.SignatureOfType(mt.Out(j)).String(), "out"} m.Args = append(m.Args, arg) } m.Annotations = make([]Annotation, 0) ms = append(ms, m) } return ms }