func (usr *User) String() string {
	usr.init()
	return fmt.Sprintf("%v:%v#%v", getTypeString(usr.typ), usr.name, usr.zone)
}
String returns a user's type, name, and zone.
package gorods
import "C"
import (
	"fmt"
	"strconv"
	"strings"
	"time"
	"unsafe"
)
type User struct {
	name        string
	zone        *Zone
	createTime  time.Time
	modifyTime  time.Time
	id          int
	typ         int
	info        string
	comment     string
	parentSlice *Users
	hasInit bool
	groups Groups
	con    *Connection
	metaCol *MetaCollection
}
type Users []*User
func initUser(name string, zone *Zone, con *Connection) (*User, error) {
	usr := new(User)
	usr.name = name
	usr.zone = zone
	usr.con = con
	return usr, nil
}
func (usr *User) Remove() bool {
	for n, p := range *usr.parentSlice {
		if p.name == usr.name {
			usr.parentSlice.Remove(n)
			return true
		}
	}
	return false
}
func (usr *User) Name() string {
	return usr.name
}
func (usr *User) Path() string {
	return usr.name
}
func (usr *User) Zone() *Zone {
	return usr.zone
}
func (usr *User) Comment() (string, error) {
	if err := usr.init(); err != nil {
		return usr.comment, err
	}
	return usr.comment, nil
}
func (usr *User) Info() (string, error) {
	if err := usr.init(); err != nil {
		return usr.info, err
	}
	return usr.info, nil
}
func (usr *User) CreateTime() (time.Time, error) {
	if err := usr.init(); err != nil {
		return usr.createTime, err
	}
	return usr.createTime, nil
}
func (usr *User) ModifyTime() (time.Time, error) {
	if err := usr.init(); err != nil {
		return usr.modifyTime, err
	}
	return usr.modifyTime, nil
}
func (usr *User) Id() (int, error) {
	if err := usr.init(); err != nil {
		return usr.id, err
	}
	return usr.id, nil
}
func (usr *User) Type() int {
	if err := usr.init(); err != nil {
		return UnknownType
	}
	return usr.typ
}
func (usr *User) Con() *Connection {
	return usr.con
}
func (usr *User) Groups() (Groups, error) {
	if err := usr.init(); err != nil {
		return nil, err
	}
	return usr.groups, nil
}
func (usr *User) Delete() error {
	if err := deleteUser(usr.Name(), usr.Zone(), usr.con); err != nil {
		return err
	}
	if err := usr.con.RefreshUsers(); err != nil {
		return err
	}
	return nil
}
func (usr *User) init() error {
	if !usr.hasInit {
		if err := usr.RefreshInfo(); err != nil {
			return err
		}
		if err := usr.RefreshGroups(); err != nil {
			return err
		}
		usr.hasInit = true
	}
	return nil
}
func (usr *User) RefreshInfo() error {
	typeMap := map[string]int{
		"rodsuser":   UserType,
		"rodsadmin":  AdminType,
		"groupadmin": GroupAdminType,
	}
	if infoMap, err := usr.FetchInfo(); err == nil {
		usr.comment = infoMap["r_comment"]
		usr.createTime = timeStringToTime(infoMap["create_ts"])
		usr.modifyTime = timeStringToTime(infoMap["modify_ts"])
		usr.id, _ = strconv.Atoi(infoMap["user_id"])
		usr.typ = typeMap[infoMap["user_type_name"]]
		usr.info = infoMap["user_info"]
		if zones, err := usr.con.Zones(); err != nil {
			return err
		} else {
			if zne := zones.FindByName(infoMap["zone_name"], usr.con); zne != nil {
				usr.zone = zne
			} else {
				return newError(Fatal, -1, fmt.Sprintf("iRODS Refresh User Info Failed: Unable to locate zone in cache"))
			}
		}
	} else {
		return err
	}
	return nil
}
func (usr *User) RefreshGroups() error {
	if grps, err := usr.FetchGroups(); err == nil {
		usr.groups = grps
	} else {
		return err
	}
	return nil
}
func (usrs Users) FindByName(name string, con *Connection) *User {
	for _, usr := range usrs {
		if usr.name == name {
			return usr
		}
	}
	zne, err := con.LocalZone()
	if err != nil {
		return nil
	}
	usr, _ := initUser(name, zne, con)
	return usr
}
func (usrs *Users) Remove(index int) {
	*usrs = append((*usrs)[:index], (*usrs)[index+1:]...)
}