Update to latest gomatrix. Things are broken
This commit is contained in:
		
							
								
								
									
										40
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										40
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							| @@ -4,14 +4,14 @@ | ||||
| [[projects]] | ||||
|   name = "github.com/davecgh/go-spew" | ||||
|   packages = ["spew"] | ||||
|   revision = "346938d642f2ec3594ed81d874461961cd0faa76" | ||||
|   version = "v1.1.0" | ||||
|   revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" | ||||
|   version = "v1.1.1" | ||||
|  | ||||
| [[projects]] | ||||
|   name = "github.com/disintegration/imaging" | ||||
|   packages = ["."] | ||||
|   revision = "bbcee2f5c9d5e94ca42c8b50ec847fec64a6c134" | ||||
|   version = "v1.4.2" | ||||
|   revision = "0bd5694c78c9c3d9a3cd06a706a8f3c59296a9ac" | ||||
|   version = "v1.5.0" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
| @@ -26,16 +26,16 @@ | ||||
|   version = "v1.5.1" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   name = "github.com/lucasb-eyer/go-colorful" | ||||
|   packages = ["."] | ||||
|   revision = "8abd3beca3a7f5039809449d6013a0254ac22bb1" | ||||
|   revision = "345fbb3dbcdb252d9985ee899a84963c0fa24c82" | ||||
|   version = "v1.0" | ||||
|  | ||||
| [[projects]] | ||||
|   name = "github.com/mattn/go-runewidth" | ||||
|   packages = ["."] | ||||
|   revision = "9e777a8366cce605130a531d2cd6363d07ad7317" | ||||
|   version = "v0.0.2" | ||||
|   revision = "ce7b0b5c7b45a81508558cd1dba6bb1e4ddb51bb" | ||||
|   version = "v0.0.3" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
| @@ -50,10 +50,10 @@ | ||||
|   version = "v1.0.0" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   name = "github.com/renstrom/fuzzysearch" | ||||
|   packages = ["fuzzy"] | ||||
|   revision = "500e0fce37a81072d9bf4ec1bf5d32f52c807282" | ||||
|   revision = "b18e754edff4833912ef4dce9eaca885bd3f0de1" | ||||
|   version = "v1.0.1" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
| @@ -64,14 +64,14 @@ | ||||
| [[projects]] | ||||
|   name = "github.com/stretchr/testify" | ||||
|   packages = ["assert"] | ||||
|   revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" | ||||
|   version = "v1.2.1" | ||||
|   revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" | ||||
|   version = "v1.2.2" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   name = "github.com/zyedidia/clipboard" | ||||
|   packages = ["."] | ||||
|   revision = "4611e809d8b1a3051c11d11f4b610c44df73fa38" | ||||
|   revision = "bd31d747117d04b4e25b61f73e1ea4faeea3c56a" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
| @@ -85,7 +85,7 @@ | ||||
|     "vp8l", | ||||
|     "webp" | ||||
|   ] | ||||
|   revision = "f315e440302883054d0c2bd85486878cb4f8572c" | ||||
|   revision = "c73c2afc3b812cdd6385de5a50616511c4a3d458" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
| @@ -94,7 +94,7 @@ | ||||
|     "html", | ||||
|     "html/atom" | ||||
|   ] | ||||
|   revision = "dfa909b99c79129e1100513e5cd36307665e5723" | ||||
|   revision = "8a410e7b638dca158bf9e766925842f6651ff828" | ||||
|  | ||||
| [[projects]] | ||||
|   name = "golang.org/x/text" | ||||
| @@ -118,7 +118,7 @@ | ||||
|   branch = "v1" | ||||
|   name = "gopkg.in/toast.v1" | ||||
|   packages = ["."] | ||||
|   revision = "b700e246b8b6d3e13554091e540e1019e26389f1" | ||||
|   revision = "0a84660828b24d25b35525c9a1f1f51267f8da91" | ||||
|  | ||||
| [[projects]] | ||||
|   name = "gopkg.in/yaml.v2" | ||||
| @@ -130,7 +130,13 @@ | ||||
|   branch = "master" | ||||
|   name = "maunium.net/go/gomatrix" | ||||
|   packages = ["."] | ||||
|   revision = "b491397f18b90e34ef54b8b3598666564b90b01a" | ||||
|   revision = "d651abc3ecb4bbd85a6b17b710632e73ddbbc6aa" | ||||
|  | ||||
| [[projects]] | ||||
|   name = "maunium.net/go/maulogger" | ||||
|   packages = ["."] | ||||
|   revision = "64f0aa33b6c51313e15575257db71dec44fe7988" | ||||
|   version = "v1.0" | ||||
|  | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   | ||||
| @@ -33,14 +33,14 @@ type MatrixContainer interface { | ||||
| 	Logout() | ||||
|  | ||||
| 	SendPreferencesToMatrix() | ||||
| 	SendMessage(roomID, msgtype, message string) (string, error) | ||||
| 	SendMarkdownMessage(roomID, msgtype, message string) (string, error) | ||||
| 	SendMessage(roomID string, msgtype gomatrix.MessageType, message string) (string, error) | ||||
| 	SendMarkdownMessage(roomID string, msgtype gomatrix.MessageType, message string) (string, error) | ||||
| 	SendTyping(roomID string, typing bool) | ||||
| 	MarkRead(roomID, eventID string) | ||||
| 	JoinRoom(roomID, server string) (*rooms.Room, error) | ||||
| 	LeaveRoom(roomID string) error | ||||
|  | ||||
| 	GetHistory(roomID, prevBatch string, limit int) ([]gomatrix.Event, string, error) | ||||
| 	GetHistory(roomID, prevBatch string, limit int) ([]*gomatrix.Event, string, error) | ||||
| 	GetRoom(roomID string) *rooms.Room | ||||
|  | ||||
| 	Download(mxcURL string) ([]byte, string, string, error) | ||||
|   | ||||
| @@ -73,8 +73,8 @@ type RoomView interface { | ||||
| 	SetTyping(users []string) | ||||
| 	UpdateUserList() | ||||
|  | ||||
| 	NewMessage(id, sender, msgtype, text string, timestamp time.Time) Message | ||||
| 	NewTempMessage(msgtype, text string) Message | ||||
| 	NewMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) Message | ||||
| 	NewTempMessage(msgtype gomatrix.MessageType, text string) Message | ||||
| 	AddMessage(message Message, direction MessageDirection) | ||||
| 	AddServiceMessage(message string) | ||||
| } | ||||
| @@ -111,8 +111,8 @@ type Message interface { | ||||
| 	SetID(id string) | ||||
| 	ID() string | ||||
|  | ||||
| 	SetType(msgtype string) | ||||
| 	Type() string | ||||
| 	SetType(msgtype gomatrix.MessageType) | ||||
| 	Type() gomatrix.MessageType | ||||
|  | ||||
| 	NotificationContent() string | ||||
|  | ||||
|   | ||||
| @@ -175,6 +175,8 @@ func (c *Container) PushRules() *pushrules.PushRuleset { | ||||
| 	return c.config.PushRules | ||||
| } | ||||
|  | ||||
| var AccountDataGomuksPreferences = gomatrix.NewEventType("net.maunium.gomuks.preferences") | ||||
|  | ||||
| // OnLogin initializes the syncer and updates the room list. | ||||
| func (c *Container) OnLogin() { | ||||
| 	c.ui.OnLogin() | ||||
| @@ -183,14 +185,14 @@ func (c *Container) OnLogin() { | ||||
|  | ||||
| 	debug.Print("Initializing syncer") | ||||
| 	c.syncer = NewGomuksSyncer(c.config) | ||||
| 	c.syncer.OnEventType("m.room.message", c.HandleMessage) | ||||
| 	c.syncer.OnEventType("m.room.member", c.HandleMembership) | ||||
| 	c.syncer.OnEventType("m.receipt", c.HandleReadReceipt) | ||||
| 	c.syncer.OnEventType("m.typing", c.HandleTyping) | ||||
| 	c.syncer.OnEventType("m.direct", c.HandleDirectChatInfo) | ||||
| 	c.syncer.OnEventType("m.push_rules", c.HandlePushRules) | ||||
| 	c.syncer.OnEventType("m.tag", c.HandleTag) | ||||
| 	c.syncer.OnEventType("net.maunium.gomuks.preferences", c.HandlePreferences) | ||||
| 	c.syncer.OnEventType(gomatrix.EventMessage, c.HandleMessage) | ||||
| 	c.syncer.OnEventType(gomatrix.StateMember, c.HandleMembership) | ||||
| 	c.syncer.OnEventType(gomatrix.EphemeralEventReceipt, c.HandleReadReceipt) | ||||
| 	c.syncer.OnEventType(gomatrix.EphemeralEventTyping, c.HandleTyping) | ||||
| 	c.syncer.OnEventType(gomatrix.AccountDataDirectChats, c.HandleDirectChatInfo) | ||||
| 	c.syncer.OnEventType(gomatrix.AccountDataPushRules, c.HandlePushRules) | ||||
| 	c.syncer.OnEventType(gomatrix.AccountDataRoomTags, c.HandleTag) | ||||
| 	c.syncer.OnEventType(AccountDataGomuksPreferences, c.HandlePreferences) | ||||
| 	c.syncer.InitDoneCallback = func() { | ||||
| 		c.config.AuthCache.InitialSyncDone = true | ||||
| 		c.config.SaveAuthCache() | ||||
| @@ -301,10 +303,10 @@ func (c *Container) HandleMembership(source EventSource, evt *gomatrix.Event) { | ||||
| } | ||||
|  | ||||
| func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) { | ||||
| 	membership, _ := evt.Content["membership"].(string) | ||||
| 	prevMembership := "leave" | ||||
| 	membership := evt.Content.Membership | ||||
| 	prevMembership := gomatrix.MembershipLeave | ||||
| 	if evt.Unsigned.PrevContent != nil { | ||||
| 		prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string) | ||||
| 		prevMembership = evt.Unsigned.PrevContent.Membership | ||||
| 	} | ||||
| 	debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID) | ||||
| 	if membership == prevMembership { | ||||
| @@ -326,7 +328,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) { | ||||
|  | ||||
| func (c *Container) parseReadReceipt(evt *gomatrix.Event) (largestTimestampEvent string) { | ||||
| 	var largestTimestamp int64 | ||||
| 	for eventID, rawContent := range evt.Content { | ||||
| 	for eventID, rawContent := range evt.Content.Raw { | ||||
| 		content, ok := rawContent.(map[string]interface{}) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| @@ -368,7 +370,7 @@ func (c *Container) HandleReadReceipt(source EventSource, evt *gomatrix.Event) { | ||||
|  | ||||
| func (c *Container) parseDirectChatInfo(evt *gomatrix.Event) map[*rooms.Room]bool { | ||||
| 	directChats := make(map[*rooms.Room]bool) | ||||
| 	for _, rawRoomIDList := range evt.Content { | ||||
| 	for _, rawRoomIDList := range evt.Content.Raw { | ||||
| 		roomIDList, ok := rawRoomIDList.([]interface{}) | ||||
| 		if !ok { | ||||
| 			continue | ||||
| @@ -416,15 +418,12 @@ func (c *Container) HandlePushRules(source EventSource, evt *gomatrix.Event) { | ||||
| func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) { | ||||
| 	room := c.config.GetRoom(evt.RoomID) | ||||
|  | ||||
| 	tags, _ := evt.Content["tags"].(map[string]interface{}) | ||||
| 	newTags := make([]rooms.RoomTag, len(tags)) | ||||
| 	newTags := make([]rooms.RoomTag, len(evt.Content.RoomTags)) | ||||
| 	index := 0 | ||||
| 	for tag, infoifc := range tags { | ||||
| 		info, _ := infoifc.(map[string]interface{}) | ||||
| 	for tag, info := range evt.Content.RoomTags { | ||||
| 		order := "0.5" | ||||
| 		rawOrder, ok := info["order"] | ||||
| 		if ok { | ||||
| 			order = fmt.Sprintf("%v", rawOrder) | ||||
| 		if len(info.Order) > 0 { | ||||
| 			order = info.Order | ||||
| 		} | ||||
| 		newTags[index] = rooms.RoomTag{ | ||||
| 			Tag:   tag, | ||||
| @@ -440,13 +439,7 @@ func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) { | ||||
|  | ||||
| // HandleTyping is the event handler for the m.typing event. | ||||
| func (c *Container) HandleTyping(source EventSource, evt *gomatrix.Event) { | ||||
| 	users := evt.Content["user_ids"].([]interface{}) | ||||
|  | ||||
| 	strUsers := make([]string, len(users)) | ||||
| 	for i, user := range users { | ||||
| 		strUsers[i] = user.(string) | ||||
| 	} | ||||
| 	c.ui.MainView().SetTyping(evt.RoomID, strUsers) | ||||
| 	c.ui.MainView().SetTyping(evt.RoomID, evt.Content.TypingUserIDs) | ||||
| } | ||||
|  | ||||
| func (c *Container) MarkRead(roomID, eventID string) { | ||||
| @@ -455,11 +448,11 @@ func (c *Container) MarkRead(roomID, eventID string) { | ||||
| } | ||||
|  | ||||
| // SendMessage sends a message with the given text to the given room. | ||||
| func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) { | ||||
| func (c *Container) SendMessage(roomID string, msgtype gomatrix.MessageType, text string) (string, error) { | ||||
| 	defer debug.Recover() | ||||
| 	c.SendTyping(roomID, false) | ||||
| 	resp, err := c.client.SendMessageEvent(roomID, "m.room.message", | ||||
| 		gomatrix.TextMessage{MsgType: msgtype, Body: text}) | ||||
| 	resp, err := c.client.SendMessageEvent(roomID, gomatrix.EventMessage, | ||||
| 		gomatrix.Content{MsgType: msgtype, Body: text}) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| @@ -498,7 +491,7 @@ var roomRegex = regexp.MustCompile("\\[.+?]\\(https://matrix.to/#/(#.+?:[^/]+?)\ | ||||
| // | ||||
| // If the given text contains markdown formatting symbols, it will be rendered into HTML before sending. | ||||
| // Otherwise, it will be sent as plain text. | ||||
| func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, error) { | ||||
| func (c *Container) SendMarkdownMessage(roomID string, msgtype gomatrix.MessageType, text string) (string, error) { | ||||
| 	defer debug.Recover() | ||||
|  | ||||
| 	html := c.renderMarkdown(text) | ||||
| @@ -511,12 +504,12 @@ func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, e | ||||
| 	text = roomRegex.ReplaceAllString(text, "$1") | ||||
|  | ||||
| 	c.SendTyping(roomID, false) | ||||
| 	resp, err := c.client.SendMessageEvent(roomID, "m.room.message", | ||||
| 		map[string]interface{}{ | ||||
| 			"msgtype":        msgtype, | ||||
| 			"body":           text, | ||||
| 			"format":         "org.matrix.custom.html", | ||||
| 			"formatted_body": html, | ||||
| 	resp, err := c.client.SendMessageEvent(roomID, gomatrix.EventMessage, | ||||
| 		gomatrix.Content{ | ||||
| 			MsgType:       msgtype, | ||||
| 			Body:          text, | ||||
| 			Format:        gomatrix.FormatHTML, | ||||
| 			FormattedBody: html, | ||||
| 		}) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| @@ -567,7 +560,7 @@ func (c *Container) LeaveRoom(roomID string) error { | ||||
| } | ||||
|  | ||||
| // GetHistory fetches room history. | ||||
| func (c *Container) GetHistory(roomID, prevBatch string, limit int) ([]gomatrix.Event, string, error) { | ||||
| func (c *Container) GetHistory(roomID, prevBatch string, limit int) ([]*gomatrix.Event, string, error) { | ||||
| 	resp, err := c.client.Messages(roomID, prevBatch, "", 'b', limit) | ||||
| 	if err != nil { | ||||
| 		return nil, "", err | ||||
|   | ||||
| @@ -23,14 +23,13 @@ import ( | ||||
|  | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"maunium.net/go/gomuks/lib/glob" | ||||
| 	"maunium.net/go/gomuks/matrix/rooms" | ||||
| ) | ||||
|  | ||||
| // Room is an interface with the functions that are needed for processing room-specific push conditions | ||||
| type Room interface { | ||||
| 	GetMember(mxid string) *rooms.Member | ||||
| 	GetMembers() map[string]*rooms.Member | ||||
| 	GetSessionOwner() *rooms.Member | ||||
| 	GetMember(mxid string) *gomatrix.Member | ||||
| 	GetMembers() map[string]*gomatrix.Member | ||||
| 	GetSessionOwner() string | ||||
| } | ||||
|  | ||||
| // PushCondKind is the type of a push condition. | ||||
| @@ -89,7 +88,7 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool { | ||||
|  | ||||
| 	switch key { | ||||
| 	case "type": | ||||
| 		return pattern.MatchString(event.Type) | ||||
| 		return pattern.MatchString(event.Type.String()) | ||||
| 	case "sender": | ||||
| 		return pattern.MatchString(event.Sender) | ||||
| 	case "room_id": | ||||
| @@ -100,7 +99,7 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool { | ||||
| 		} | ||||
| 		return pattern.MatchString(*event.StateKey) | ||||
| 	case "content": | ||||
| 		val, _ := event.Content[subkey].(string) | ||||
| 		val, _ := event.Content.Raw[subkey].(string) | ||||
| 		return pattern.MatchString(val) | ||||
| 	default: | ||||
| 		return false | ||||
| @@ -108,12 +107,12 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool { | ||||
| } | ||||
|  | ||||
| func (cond *PushCondition) matchDisplayName(room Room, event *gomatrix.Event) bool { | ||||
| 	member := room.GetSessionOwner() | ||||
| 	if member == nil || member.UserID == event.Sender { | ||||
| 	ownerID := room.GetSessionOwner() | ||||
| 	if ownerID == event.Sender { | ||||
| 		return false | ||||
| 	} | ||||
| 	text, _ := event.Content["body"].(string) | ||||
| 	return strings.Contains(text, member.DisplayName) | ||||
| 	member := room.GetMember(ownerID) | ||||
| 	return strings.Contains(event.Content.Body, member.Displayname) | ||||
| } | ||||
|  | ||||
| func (cond *PushCondition) matchMemberCount(room Room, event *gomatrix.Event) bool { | ||||
|   | ||||
| @@ -21,19 +21,17 @@ func GetScopedPushRules(client *gomatrix.Client, scope string) (resp *PushRulese | ||||
| 	return | ||||
| } | ||||
|  | ||||
| type contentWithRuleset struct { | ||||
| 	Ruleset *PushRuleset `json:"global"` | ||||
| } | ||||
|  | ||||
| // EventToPushRules converts a m.push_rules event to a PushRuleset by passing the data through JSON. | ||||
| func EventToPushRules(event *gomatrix.Event) (*PushRuleset, error) { | ||||
| 	content, _ := event.Content["global"] | ||||
| 	raw, err := json.Marshal(content) | ||||
| 	content := &contentWithRuleset{} | ||||
| 	err := json.Unmarshal(event.Content.VeryRaw, content) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ruleset := &PushRuleset{} | ||||
| 	err = json.Unmarshal(raw, ruleset) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return ruleset, nil | ||||
| 	return content.Ruleset, nil | ||||
| } | ||||
|   | ||||
| @@ -154,6 +154,5 @@ func (rule *PushRule) matchPattern(room Room, event *gomatrix.Event) bool { | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	text, _ := event.Content["body"].(string) | ||||
| 	return pattern.MatchString(text) | ||||
| 	return pattern.MatchString(event.Content.Body) | ||||
| } | ||||
|   | ||||
| @@ -1,63 +0,0 @@ | ||||
| // gomuks - A terminal Matrix client written in Go. | ||||
| // Copyright (C) 2018 Tulir Asokan | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| package rooms | ||||
|  | ||||
| import ( | ||||
| 	"maunium.net/go/gomatrix" | ||||
| ) | ||||
|  | ||||
| // Membership is an enum specifying the membership state of a room member. | ||||
| type Membership string | ||||
|  | ||||
| // The allowed membership states as specified in spec section 10.5.5. | ||||
| const ( | ||||
| 	MembershipJoin   Membership = "join" | ||||
| 	MembershipLeave  Membership = "leave" | ||||
| 	MembershipInvite Membership = "invite" | ||||
| 	MembershipBan    Membership = "ban" | ||||
| 	MembershipKnock  Membership = "knock" | ||||
| ) | ||||
|  | ||||
| // Member represents a member in a room. | ||||
| type Member struct { | ||||
| 	// The MXID of the member. | ||||
| 	UserID string `json:"-"` | ||||
| 	// The membership status. Defaults to leave. | ||||
| 	Membership Membership `json:"membership"` | ||||
| 	// The display name of the user. Defaults to the user ID. | ||||
| 	DisplayName string `json:"displayname"` | ||||
| 	// The avatar URL of the user. Defaults to an empty string. | ||||
| 	AvatarURL string `json:"avatar_url"` | ||||
| } | ||||
|  | ||||
| // eventToRoomMember converts a m.room.member state event into a Member object. | ||||
| func eventToRoomMember(userID string, event *gomatrix.Event) *Member { | ||||
| 	membership, _ := event.Content["membership"].(string) | ||||
| 	avatarURL, _ := event.Content["avatar_url"].(string) | ||||
|  | ||||
| 	displayName, _ := event.Content["displayname"].(string) | ||||
| 	if len(displayName) == 0 { | ||||
| 		displayName = userID | ||||
| 	} | ||||
|  | ||||
| 	return &Member{ | ||||
| 		UserID:      userID, | ||||
| 		Membership:  Membership(membership), | ||||
| 		DisplayName: displayName, | ||||
| 		AvatarURL:   avatarURL, | ||||
| 	} | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| // gomuks - A terminal Matrix client written in Go. | ||||
| // Copyright (C) 2018 Tulir Asokan | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| package rooms_test | ||||
| @@ -82,10 +82,10 @@ type Room struct { | ||||
| 	LastReceivedMessage time.Time | ||||
|  | ||||
| 	// MXID -> Member cache calculated from membership events. | ||||
| 	memberCache map[string]*Member | ||||
| 	memberCache map[string]*gomatrix.Member | ||||
| 	// The first non-SessionUserID member in the room. Calculated at | ||||
| 	// the same time as memberCache. | ||||
| 	firstMemberCache *Member | ||||
| 	firstMemberCache *gomatrix.Member | ||||
| 	// The name of the room. Calculated from the state event name, | ||||
| 	// canonical_alias or alias or the member cache. | ||||
| 	nameCache string | ||||
| @@ -222,25 +222,25 @@ func (room *Room) UpdateState(event *gomatrix.Event) { | ||||
| 		room.State[event.Type] = make(map[string]*gomatrix.Event) | ||||
| 	} | ||||
| 	switch event.Type { | ||||
| 	case "m.room.name": | ||||
| 	case gomatrix.StateRoomName: | ||||
| 		room.nameCache = "" | ||||
| 	case "m.room.canonical_alias": | ||||
| 	case gomatrix.StateCanonicalAlias: | ||||
| 		if room.nameCacheSource >= CanonicalAliasRoomName { | ||||
| 			room.nameCache = "" | ||||
| 		} | ||||
| 		room.canonicalAliasCache = "" | ||||
| 	case "m.room.aliases": | ||||
| 	case gomatrix.StateAliases: | ||||
| 		if room.nameCacheSource >= AliasRoomName { | ||||
| 			room.nameCache = "" | ||||
| 		} | ||||
| 		room.aliasesCache = nil | ||||
| 	case "m.room.member": | ||||
| 	case gomatrix.StateMember: | ||||
| 		room.memberCache = nil | ||||
| 		room.firstMemberCache = nil | ||||
| 		if room.nameCacheSource >= MemberRoomName { | ||||
| 			room.nameCache = "" | ||||
| 		} | ||||
| 	case "m.room.topic": | ||||
| 	case gomatrix.StateTopic: | ||||
| 		room.topicCache = "" | ||||
| 	} | ||||
|  | ||||
| @@ -248,7 +248,7 @@ func (room *Room) UpdateState(event *gomatrix.Event) { | ||||
| 	if event.StateKey != nil { | ||||
| 		stateKey = *event.StateKey | ||||
| 	} | ||||
| 	if event.Type != "m.room.member" { | ||||
| 	if event.Type != gomatrix.StateMember { | ||||
| 		debug.Printf("Updating state %s#%s for %s", event.Type, stateKey, room.ID) | ||||
| 	} | ||||
|  | ||||
| @@ -260,14 +260,14 @@ func (room *Room) UpdateState(event *gomatrix.Event) { | ||||
| } | ||||
|  | ||||
| // GetStateEvent returns the state event for the given type/state_key combo, or nil. | ||||
| func (room *Room) GetStateEvent(eventType string, stateKey string) *gomatrix.Event { | ||||
| func (room *Room) GetStateEvent(eventType gomatrix.EventType, stateKey string) *gomatrix.Event { | ||||
| 	stateEventMap, _ := room.State[eventType] | ||||
| 	event, _ := stateEventMap[stateKey] | ||||
| 	return event | ||||
| } | ||||
|  | ||||
| // GetStateEvents returns the state events for the given type. | ||||
| func (room *Room) GetStateEvents(eventType string) map[string]*gomatrix.Event { | ||||
| func (room *Room) GetStateEvents(eventType gomatrix.EventType) map[string]*gomatrix.Event { | ||||
| 	stateEventMap, _ := room.State[eventType] | ||||
| 	return stateEventMap | ||||
| } | ||||
| @@ -275,9 +275,9 @@ func (room *Room) GetStateEvents(eventType string) map[string]*gomatrix.Event { | ||||
| // GetTopic returns the topic of the room. | ||||
| func (room *Room) GetTopic() string { | ||||
| 	if len(room.topicCache) == 0 { | ||||
| 		topicEvt := room.GetStateEvent("m.room.topic", "") | ||||
| 		topicEvt := room.GetStateEvent(gomatrix.StateTopic, "") | ||||
| 		if topicEvt != nil { | ||||
| 			room.topicCache, _ = topicEvt.Content["topic"].(string) | ||||
| 			room.topicCache = topicEvt.Content.Topic | ||||
| 		} | ||||
| 	} | ||||
| 	return room.topicCache | ||||
| @@ -285,9 +285,9 @@ func (room *Room) GetTopic() string { | ||||
|  | ||||
| func (room *Room) GetCanonicalAlias() string { | ||||
| 	if len(room.canonicalAliasCache) == 0 { | ||||
| 		canonicalAliasEvt := room.GetStateEvent("m.room.canonical_alias", "") | ||||
| 		canonicalAliasEvt := room.GetStateEvent(gomatrix.StateCanonicalAlias, "") | ||||
| 		if canonicalAliasEvt != nil { | ||||
| 			room.canonicalAliasCache, _ = canonicalAliasEvt.Content["alias"].(string) | ||||
| 			room.canonicalAliasCache = canonicalAliasEvt.Content.Alias | ||||
| 		} else { | ||||
| 			room.canonicalAliasCache = "-" | ||||
| 		} | ||||
| @@ -301,17 +301,10 @@ func (room *Room) GetCanonicalAlias() string { | ||||
| // GetAliases returns the list of aliases that point to this room. | ||||
| func (room *Room) GetAliases() []string { | ||||
| 	if room.aliasesCache == nil { | ||||
| 		aliasEvents := room.GetStateEvents("m.room.aliases") | ||||
| 		aliasEvents := room.GetStateEvents(gomatrix.StateAliases) | ||||
| 		room.aliasesCache = []string{} | ||||
| 		for _, event := range aliasEvents { | ||||
| 			aliases, _ := event.Content["aliases"].([]interface{}) | ||||
|  | ||||
| 			newAliases := make([]string, len(room.aliasesCache)+len(aliases)) | ||||
| 			copy(newAliases, room.aliasesCache) | ||||
| 			for index, alias := range aliases { | ||||
| 				newAliases[len(room.aliasesCache)+index], _ = alias.(string) | ||||
| 			} | ||||
| 			room.aliasesCache = newAliases | ||||
| 			room.aliasesCache = append(room.aliasesCache, event.Content.Aliases...) | ||||
| 		} | ||||
| 	} | ||||
| 	return room.aliasesCache | ||||
| @@ -319,9 +312,9 @@ func (room *Room) GetAliases() []string { | ||||
|  | ||||
| // updateNameFromNameEvent updates the room display name to be the name set in the name event. | ||||
| func (room *Room) updateNameFromNameEvent() { | ||||
| 	nameEvt := room.GetStateEvent("m.room.name", "") | ||||
| 	nameEvt := room.GetStateEvent(gomatrix.StateRoomName, "") | ||||
| 	if nameEvt != nil { | ||||
| 		room.nameCache, _ = nameEvt.Content["name"].(string) | ||||
| 		room.nameCache = nameEvt.Content.Name | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -353,9 +346,9 @@ func (room *Room) updateNameFromMembers() { | ||||
| 	} else if room.firstMemberCache == nil { | ||||
| 		room.nameCache = "Room" | ||||
| 	} else if len(members) == 2 { | ||||
| 		room.nameCache = room.firstMemberCache.DisplayName | ||||
| 		room.nameCache = room.firstMemberCache.Displayname | ||||
| 	} else { | ||||
| 		firstMember := room.firstMemberCache.DisplayName | ||||
| 		firstMember := room.firstMemberCache.Displayname | ||||
| 		room.nameCache = fmt.Sprintf("%s and %d others", firstMember, len(members)-2) | ||||
| 	} | ||||
| } | ||||
| @@ -391,18 +384,18 @@ func (room *Room) GetTitle() string { | ||||
| } | ||||
|  | ||||
| // createMemberCache caches all member events into a easily processable MXID -> *Member map. | ||||
| func (room *Room) createMemberCache() map[string]*Member { | ||||
| 	cache := make(map[string]*Member) | ||||
| 	events := room.GetStateEvents("m.room.member") | ||||
| func (room *Room) createMemberCache() map[string]*gomatrix.Member { | ||||
| 	cache := make(map[string]*gomatrix.Member) | ||||
| 	events := room.GetStateEvents(gomatrix.StateMember) | ||||
| 	room.firstMemberCache = nil | ||||
| 	if events != nil { | ||||
| 		for userID, event := range events { | ||||
| 			member := eventToRoomMember(userID, event) | ||||
| 			member := &event.Content.Member | ||||
| 			if room.firstMemberCache == nil && userID != room.SessionUserID { | ||||
| 				room.firstMemberCache = member | ||||
| 			} | ||||
| 			if member.Membership != "leave" { | ||||
| 				cache[member.UserID] = member | ||||
| 				cache[userID] = member | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -414,7 +407,7 @@ func (room *Room) createMemberCache() map[string]*Member { | ||||
| // | ||||
| // The members are returned from the cache. | ||||
| // If the cache is empty, it is updated first. | ||||
| func (room *Room) GetMembers() map[string]*Member { | ||||
| func (room *Room) GetMembers() map[string]*gomatrix.Member { | ||||
| 	if len(room.memberCache) == 0 || room.firstMemberCache == nil { | ||||
| 		room.createMemberCache() | ||||
| 	} | ||||
| @@ -423,7 +416,7 @@ func (room *Room) GetMembers() map[string]*Member { | ||||
|  | ||||
| // GetMember returns the member with the given MXID. | ||||
| // If the member doesn't exist, nil is returned. | ||||
| func (room *Room) GetMember(userID string) *Member { | ||||
| func (room *Room) GetMember(userID string) *gomatrix.Member { | ||||
| 	if len(room.memberCache) == 0 { | ||||
| 		room.createMemberCache() | ||||
| 	} | ||||
| @@ -432,8 +425,8 @@ func (room *Room) GetMember(userID string) *Member { | ||||
| } | ||||
|  | ||||
| // GetSessionOwner returns the Member instance of the user whose session this room was created for. | ||||
| func (room *Room) GetSessionOwner() *Member { | ||||
| 	return room.GetMember(room.SessionUserID) | ||||
| func (room *Room) GetSessionOwner() string { | ||||
| 	return room.SessionUserID | ||||
| } | ||||
|  | ||||
| // NewRoom creates a new Room with the given ID | ||||
|   | ||||
| @@ -51,7 +51,7 @@ type EventHandler func(source EventSource, event *gomatrix.Event) | ||||
| // pattern to notify callers about incoming events. See GomuksSyncer.OnEventType for more information. | ||||
| type GomuksSyncer struct { | ||||
| 	Session          SyncerSession | ||||
| 	listeners        map[string][]EventHandler // event type to listeners array | ||||
| 	listeners        map[gomatrix.EventType][]EventHandler // event type to listeners array | ||||
| 	FirstSyncDone    bool | ||||
| 	InitDoneCallback func() | ||||
| } | ||||
| @@ -60,7 +60,7 @@ type GomuksSyncer struct { | ||||
| func NewGomuksSyncer(session SyncerSession) *GomuksSyncer { | ||||
| 	return &GomuksSyncer{ | ||||
| 		Session:       session, | ||||
| 		listeners:     make(map[string][]EventHandler), | ||||
| 		listeners:     make(map[gomatrix.EventType][]EventHandler), | ||||
| 		FirstSyncDone: false, | ||||
| 	} | ||||
| } | ||||
| @@ -114,20 +114,11 @@ func (s *GomuksSyncer) processSyncEvents(room *rooms.Room, events []*gomatrix.Ev | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isState(event *gomatrix.Event) bool { | ||||
| 	switch event.Type { | ||||
| 	case "m.room.member", "m.room.name", "m.room.topic", "m.room.aliases", "m.room.canonical_alias": | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *GomuksSyncer) processSyncEvent(room *rooms.Room, event *gomatrix.Event, source EventSource) { | ||||
| 	if room != nil { | ||||
| 		event.RoomID = room.ID | ||||
| 	} | ||||
| 	if isState(event) { | ||||
| 	if event.Type.Class == gomatrix.StateEventType { | ||||
| 		room.UpdateState(event) | ||||
| 	} | ||||
| 	s.notifyListeners(source, event) | ||||
| @@ -135,7 +126,7 @@ func (s *GomuksSyncer) processSyncEvent(room *rooms.Room, event *gomatrix.Event, | ||||
|  | ||||
| // OnEventType allows callers to be notified when there are new events for the given event type. | ||||
| // There are no duplicate checks. | ||||
| func (s *GomuksSyncer) OnEventType(eventType string, callback EventHandler) { | ||||
| func (s *GomuksSyncer) OnEventType(eventType gomatrix.EventType, callback EventHandler) { | ||||
| 	_, exists := s.listeners[eventType] | ||||
| 	if !exists { | ||||
| 		s.listeners[eventType] = []EventHandler{} | ||||
|   | ||||
| @@ -19,6 +19,7 @@ package ui | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
|  | ||||
| @@ -132,7 +133,7 @@ func cmdSendEvent(cmd *Command) { | ||||
| 		return | ||||
| 	} | ||||
| 	roomID := cmd.Args[0] | ||||
| 	eventType := cmd.Args[1] | ||||
| 	eventType := gomatrix.NewEventType(cmd.Args[1]) | ||||
| 	rawContent := strings.Join(cmd.Args[2:], "") | ||||
| 	debug.Print(roomID, eventType, rawContent) | ||||
|  | ||||
| @@ -161,7 +162,7 @@ func cmdSetState(cmd *Command) { | ||||
| 	} | ||||
|  | ||||
| 	roomID := cmd.Args[0] | ||||
| 	eventType := cmd.Args[1] | ||||
| 	eventType := gomatrix.NewEventType(cmd.Args[1]) | ||||
| 	stateKey := cmd.Args[2] | ||||
| 	if stateKey == "-" { | ||||
| 		stateKey = "" | ||||
|   | ||||
| @@ -18,6 +18,7 @@ package messages | ||||
|  | ||||
| import ( | ||||
| 	"encoding/gob" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"time" | ||||
|  | ||||
| 	"maunium.net/go/gomuks/config" | ||||
| @@ -33,7 +34,7 @@ func init() { | ||||
|  | ||||
| type BaseMessage struct { | ||||
| 	MsgID           string | ||||
| 	MsgType         string | ||||
| 	MsgType         gomatrix.MessageType | ||||
| 	MsgSenderID     string | ||||
| 	MsgSender       string | ||||
| 	MsgSenderColor  tcell.Color | ||||
| @@ -47,7 +48,7 @@ type BaseMessage struct { | ||||
| 	prevPrefs       config.UserPreferences | ||||
| } | ||||
|  | ||||
| func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time) BaseMessage { | ||||
| func newBaseMessage(id, sender, displayname string, msgtype gomatrix.MessageType, timestamp time.Time) BaseMessage { | ||||
| 	return BaseMessage{ | ||||
| 		MsgSenderID:     sender, | ||||
| 		MsgSender:       displayname, | ||||
| @@ -194,11 +195,11 @@ func (msg *BaseMessage) SetID(id string) { | ||||
| 	msg.MsgID = id | ||||
| } | ||||
|  | ||||
| func (msg *BaseMessage) Type() string { | ||||
| func (msg *BaseMessage) Type() gomatrix.MessageType { | ||||
| 	return msg.MsgType | ||||
| } | ||||
|  | ||||
| func (msg *BaseMessage) SetType(msgtype string) { | ||||
| func (msg *BaseMessage) SetType(msgtype gomatrix.MessageType) { | ||||
| 	msg.MsgType = msgtype | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,7 @@ package messages | ||||
|  | ||||
| import ( | ||||
| 	"encoding/gob" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"time" | ||||
|  | ||||
| 	"maunium.net/go/gomuks/config" | ||||
| @@ -34,7 +35,7 @@ type ExpandedTextMessage struct { | ||||
| } | ||||
|  | ||||
| // NewExpandedTextMessage creates a new ExpandedTextMessage object with the provided values and the default state. | ||||
| func NewExpandedTextMessage(id, sender, displayname, msgtype string, text tstring.TString, timestamp time.Time) UIMessage { | ||||
| func NewExpandedTextMessage(id, sender, displayname string, msgtype gomatrix.MessageType, text tstring.TString, timestamp time.Time) UIMessage { | ||||
| 	return &ExpandedTextMessage{ | ||||
| 		BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp), | ||||
| 		MsgText:     text, | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/gob" | ||||
| 	"fmt" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"time" | ||||
|  | ||||
| 	"image/color" | ||||
| @@ -47,7 +48,7 @@ type ImageMessage struct { | ||||
| } | ||||
|  | ||||
| // NewImageMessage creates a new ImageMessage object with the provided values and the default state. | ||||
| func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname, msgtype, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage { | ||||
| func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname string, msgtype gomatrix.MessageType, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage { | ||||
| 	return &ImageMessage{ | ||||
| 		newBaseMessage(id, sender, displayname, msgtype, timestamp), | ||||
| 		body, | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/lucasb-eyer/go-colorful" | ||||
| 	"golang.org/x/net/html" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"maunium.net/go/gomuks/matrix/rooms" | ||||
| @@ -29,7 +30,6 @@ import ( | ||||
| 	"maunium.net/go/gomuks/ui/widget" | ||||
| 	"maunium.net/go/tcell" | ||||
| 	"strconv" | ||||
| 	"github.com/lucasb-eyer/go-colorful" | ||||
| ) | ||||
|  | ||||
| var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)") | ||||
| @@ -173,7 +173,7 @@ func (parser *htmlParser) linkToTString(node *html.Node, stripLinebreak bool) ts | ||||
| 		pillTarget := match[1] | ||||
| 		if pillTarget[0] == '@' { | ||||
| 			if member := parser.room.GetMember(pillTarget); member != nil { | ||||
| 				return tstring.NewColorTString(member.DisplayName, widget.GetHashColor(member.UserID)) | ||||
| 				return tstring.NewColorTString(member.Displayname, widget.GetHashColor(pillTarget)) | ||||
| 			} | ||||
| 		} | ||||
| 		return tstring.NewTString(pillTarget) | ||||
| @@ -271,14 +271,13 @@ func (parser *htmlParser) Parse(htmlData string) tstring.TString { | ||||
|  | ||||
| // ParseHTMLMessage parses a HTML-formatted Matrix event into a UIMessage. | ||||
| func ParseHTMLMessage(room *rooms.Room, evt *gomatrix.Event, senderDisplayname string) tstring.TString { | ||||
| 	htmlData, _ := evt.Content["formatted_body"].(string) | ||||
| 	htmlData := evt.Content.FormattedBody | ||||
| 	htmlData = strings.Replace(htmlData, "\t", "    ", -1) | ||||
|  | ||||
| 	parser := htmlParser{room} | ||||
| 	str := parser.Parse(htmlData) | ||||
|  | ||||
| 	msgtype, _ := evt.Content["msgtype"].(string) | ||||
| 	if msgtype == "m.emote" { | ||||
| 	if evt.Content.MsgType == gomatrix.MsgEmote { | ||||
| 		str = tstring.Join([]tstring.TString{ | ||||
| 			tstring.NewTString("* "), | ||||
| 			tstring.NewColorTString(senderDisplayname, widget.GetHashColor(evt.Sender)), | ||||
|   | ||||
| @@ -33,9 +33,9 @@ import ( | ||||
|  | ||||
| func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage { | ||||
| 	switch evt.Type { | ||||
| 	case "m.room.message": | ||||
| 	case gomatrix.EventMessage: | ||||
| 		return ParseMessage(matrix, room, evt) | ||||
| 	case "m.room.member": | ||||
| 	case gomatrix.StateMember: | ||||
| 		return ParseMembershipEvent(room, evt) | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -53,32 +53,28 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Ev | ||||
| 	displayname := evt.Sender | ||||
| 	member := room.GetMember(evt.Sender) | ||||
| 	if member != nil { | ||||
| 		displayname = member.DisplayName | ||||
| 		displayname = member.Displayname | ||||
| 	} | ||||
| 	msgtype, _ := evt.Content["msgtype"].(string) | ||||
| 	text, _ := evt.Content["body"].(string) | ||||
| 	ts := unixToTime(evt.Timestamp) | ||||
| 	switch msgtype { | ||||
| 	switch evt.Content.MsgType { | ||||
| 	case "m.text", "m.notice", "m.emote": | ||||
| 		format, hasFormat := evt.Content["format"].(string) | ||||
| 		if hasFormat && format == "org.matrix.custom.html" { | ||||
| 		if evt.Content.Format == gomatrix.FormatHTML { | ||||
| 			text := ParseHTMLMessage(room, evt, displayname) | ||||
| 			return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts) | ||||
| 			return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, text, ts) | ||||
| 		} | ||||
| 		text = strings.Replace(text, "\t", "    ", -1) | ||||
| 		return messages.NewTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts) | ||||
| 		evt.Content.Body = strings.Replace(evt.Content.Body, "\t", "    ", -1) | ||||
| 		return messages.NewTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, ts) | ||||
| 	case "m.image": | ||||
| 		url, _ := evt.Content["url"].(string) | ||||
| 		data, hs, id, err := matrix.Download(url) | ||||
| 		data, hs, id, err := matrix.Download(evt.Content.URL) | ||||
| 		if err != nil { | ||||
| 			debug.Printf("Failed to download %s: %v", url, err) | ||||
| 			debug.Printf("Failed to download %s: %v", evt.Content.URL, err) | ||||
| 		} | ||||
| 		return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, msgtype, text, hs, id, data, ts) | ||||
| 		return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, hs, id, data, ts) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) { | ||||
| func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership gomatrix.Membership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) { | ||||
| 	switch membership { | ||||
| 	case "invite": | ||||
| 		sender = "---" | ||||
| @@ -92,12 +88,11 @@ func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership, | ||||
| 	case "leave": | ||||
| 		sender = "<--" | ||||
| 		if evt.Sender != *evt.StateKey { | ||||
| 			if prevMembership == "ban" { | ||||
| 			if prevMembership == gomatrix.MembershipBan { | ||||
| 				text = tstring.NewColorTString(fmt.Sprintf("%s unbanned %s", senderDisplayname, displayname), tcell.ColorGreen) | ||||
| 				text.Colorize(len(senderDisplayname)+len(" unbanned "), len(displayname), widget.GetHashColor(*evt.StateKey)) | ||||
| 			} else { | ||||
| 				reason, _ := evt.Content["reason"].(string) | ||||
| 				text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, reason), tcell.ColorRed) | ||||
| 				text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed) | ||||
| 				text.Colorize(len(senderDisplayname)+len(" kicked "), len(displayname), widget.GetHashColor(*evt.StateKey)) | ||||
| 			} | ||||
| 			text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender)) | ||||
| @@ -109,8 +104,7 @@ func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership, | ||||
| 			text.Colorize(0, len(displayname), widget.GetHashColor(*evt.StateKey)) | ||||
| 		} | ||||
| 	case "ban": | ||||
| 		reason, _ := evt.Content["reason"].(string) | ||||
| 		text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, reason), tcell.ColorRed) | ||||
| 		text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed) | ||||
| 		text.Colorize(len(senderDisplayname)+len(" banned "), len(displayname), widget.GetHashColor(*evt.StateKey)) | ||||
| 		text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender)) | ||||
| 	} | ||||
| @@ -121,20 +115,20 @@ func getMembershipEventContent(room *rooms.Room, evt *gomatrix.Event) (sender st | ||||
| 	member := room.GetMember(evt.Sender) | ||||
| 	senderDisplayname := evt.Sender | ||||
| 	if member != nil { | ||||
| 		senderDisplayname = member.DisplayName | ||||
| 		senderDisplayname = member.Displayname | ||||
| 	} | ||||
|  | ||||
| 	membership, _ := evt.Content["membership"].(string) | ||||
| 	displayname, _ := evt.Content["displayname"].(string) | ||||
| 	membership := evt.Content.Membership | ||||
| 	displayname := evt.Content.Displayname | ||||
| 	if len(displayname) == 0 { | ||||
| 		displayname = *evt.StateKey | ||||
| 	} | ||||
|  | ||||
| 	prevMembership := "leave" | ||||
| 	prevMembership := gomatrix.MembershipLeave | ||||
| 	prevDisplayname := *evt.StateKey | ||||
| 	if evt.Unsigned.PrevContent != nil { | ||||
| 		prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string) | ||||
| 		prevDisplayname, _ = evt.Unsigned.PrevContent["displayname"].(string) | ||||
| 		prevMembership = evt.Unsigned.PrevContent.Membership | ||||
| 		prevDisplayname = evt.Unsigned.PrevContent.Displayname | ||||
| 		if len(prevDisplayname) == 0 { | ||||
| 			prevDisplayname = *evt.StateKey | ||||
| 		} | ||||
|   | ||||
| @@ -19,6 +19,7 @@ package messages | ||||
| import ( | ||||
| 	"encoding/gob" | ||||
| 	"fmt" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"time" | ||||
|  | ||||
| 	"maunium.net/go/gomuks/config" | ||||
| @@ -37,7 +38,7 @@ type TextMessage struct { | ||||
| } | ||||
|  | ||||
| // NewTextMessage creates a new UITextMessage object with the provided values and the default state. | ||||
| func NewTextMessage(id, sender, displayname, msgtype, text string, timestamp time.Time) UIMessage { | ||||
| func NewTextMessage(id, sender, displayname string, msgtype gomatrix.MessageType, text string, timestamp time.Time) UIMessage { | ||||
| 	return &TextMessage{ | ||||
| 		BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp), | ||||
| 		MsgText:     text, | ||||
| @@ -57,7 +58,7 @@ func (msg *TextMessage) getCache() tstring.TString { | ||||
| 	return msg.cache | ||||
| } | ||||
|  | ||||
| func (msg *TextMessage) SetType(msgtype string) { | ||||
| func (msg *TextMessage) SetType(msgtype gomatrix.MessageType) { | ||||
| 	msg.BaseMessage.SetType(msgtype) | ||||
| 	msg.cache = nil | ||||
| } | ||||
|   | ||||
| @@ -18,6 +18,7 @@ package ui | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"maunium.net/go/gomatrix" | ||||
| 	"path/filepath" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| @@ -242,7 +243,7 @@ func (view *RoomView) SetTyping(users []string) { | ||||
| 	for index, user := range users { | ||||
| 		member := view.Room.GetMember(user) | ||||
| 		if member != nil { | ||||
| 			users[index] = member.DisplayName | ||||
| 			users[index] = member.Displayname | ||||
| 		} | ||||
| 	} | ||||
| 	view.typing = users | ||||
| @@ -255,14 +256,14 @@ type completion struct { | ||||
|  | ||||
| func (view *RoomView) autocompleteUser(existingText string) (completions []completion) { | ||||
| 	textWithoutPrefix := strings.TrimPrefix(existingText, "@") | ||||
| 	for _, user := range view.Room.GetMembers() { | ||||
| 		if user.DisplayName == textWithoutPrefix || user.UserID == existingText { | ||||
| 	for userID, user := range view.Room.GetMembers() { | ||||
| 		if user.Displayname == textWithoutPrefix || userID == existingText { | ||||
| 			// Exact match, return that. | ||||
| 			return []completion{{user.DisplayName, user.UserID}} | ||||
| 			return []completion{{user.Displayname, userID}} | ||||
| 		} | ||||
|  | ||||
| 		if strings.HasPrefix(user.DisplayName, textWithoutPrefix) || strings.HasPrefix(user.UserID, existingText) { | ||||
| 			completions = append(completions, completion{user.DisplayName, user.UserID}) | ||||
| 		if strings.HasPrefix(user.Displayname, textWithoutPrefix) || strings.HasPrefix(userID, existingText) { | ||||
| 			completions = append(completions, completion{user.Displayname, userID}) | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| @@ -330,12 +331,12 @@ func (view *RoomView) MxRoom() *rooms.Room { | ||||
| func (view *RoomView) UpdateUserList() { | ||||
| 	var joined strings.Builder | ||||
| 	var invited strings.Builder | ||||
| 	for _, user := range view.Room.GetMembers() { | ||||
| 	for userID, user := range view.Room.GetMembers() { | ||||
| 		if user.Membership == "join" { | ||||
| 			joined.WriteString(widget.AddColor(user.DisplayName, widget.GetHashColorName(user.UserID))) | ||||
| 			joined.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID))) | ||||
| 			joined.WriteRune('\n') | ||||
| 		} else if user.Membership == "invite" { | ||||
| 			invited.WriteString(widget.AddColor(user.DisplayName, widget.GetHashColorName(user.UserID))) | ||||
| 			invited.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID))) | ||||
| 			invited.WriteRune('\n') | ||||
| 		} | ||||
| 	} | ||||
| @@ -346,26 +347,26 @@ func (view *RoomView) UpdateUserList() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (view *RoomView) newUIMessage(id, sender, msgtype, text string, timestamp time.Time) messages.UIMessage { | ||||
| func (view *RoomView) newUIMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) messages.UIMessage { | ||||
| 	member := view.Room.GetMember(sender) | ||||
| 	displayname := sender | ||||
| 	if member != nil { | ||||
| 		displayname = member.DisplayName | ||||
| 		displayname = member.Displayname | ||||
| 	} | ||||
| 	msg := messages.NewTextMessage(id, sender, displayname, msgtype, text, timestamp) | ||||
| 	return msg | ||||
| } | ||||
|  | ||||
| func (view *RoomView) NewMessage(id, sender, msgtype, text string, timestamp time.Time) ifc.Message { | ||||
| func (view *RoomView) NewMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) ifc.Message { | ||||
| 	return view.newUIMessage(id, sender, msgtype, text, timestamp) | ||||
| } | ||||
|  | ||||
| func (view *RoomView) NewTempMessage(msgtype, text string) ifc.Message { | ||||
| func (view *RoomView) NewTempMessage(msgtype gomatrix.MessageType, text string) ifc.Message { | ||||
| 	now := time.Now() | ||||
| 	id := strconv.FormatInt(now.UnixNano(), 10) | ||||
| 	sender := "" | ||||
| 	if ownerMember := view.Room.GetSessionOwner(); ownerMember != nil { | ||||
| 		sender = ownerMember.DisplayName | ||||
| 	if ownerMember := view.Room.GetMember(view.Room.GetSessionOwner()); ownerMember != nil { | ||||
| 		sender = ownerMember.Displayname | ||||
| 	} | ||||
| 	message := view.newUIMessage(id, sender, msgtype, text, now) | ||||
| 	message.SetState(ifc.MessageStateSending) | ||||
|   | ||||
| @@ -497,7 +497,7 @@ func (view *MainView) LoadHistory(room string) { | ||||
| 	} | ||||
| 	roomView.Room.PrevBatch = prevBatch | ||||
| 	for _, evt := range history { | ||||
| 		message := view.ParseEvent(roomView, &evt) | ||||
| 		message := view.ParseEvent(roomView, evt) | ||||
| 		if message != nil { | ||||
| 			roomView.AddMessage(message, ifc.PrependMessage) | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/davecgh/go-spew/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/davecgh/go-spew/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,7 +2,7 @@ ISC License | ||||
|  | ||||
| Copyright (c) 2012-2016 Dave Collins <dave@davec.name> | ||||
|  | ||||
| Permission to use, copy, modify, and distribute this software for any | ||||
| Permission to use, copy, modify, and/or distribute this software for any | ||||
| purpose with or without fee is hereby granted, provided that the above | ||||
| copyright notice and this permission notice appear in all copies. | ||||
|  | ||||
|   | ||||
							
								
								
									
										183
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										183
									
								
								vendor/github.com/davecgh/go-spew/spew/bypass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -16,7 +16,9 @@ | ||||
| // when the code is not running on Google App Engine, compiled by GopherJS, and | ||||
| // "-tags safe" is not added to the go build command line.  The "disableunsafe" | ||||
| // tag is deprecated and thus should not be used. | ||||
| // +build !js,!appengine,!safe,!disableunsafe | ||||
| // Go versions prior to 1.4 are disabled because they use a different layout | ||||
| // for interfaces which make the implementation of unsafeReflectValue more complex. | ||||
| // +build !js,!appengine,!safe,!disableunsafe,go1.4 | ||||
|  | ||||
| package spew | ||||
|  | ||||
| @@ -34,80 +36,49 @@ const ( | ||||
| 	ptrSize = unsafe.Sizeof((*byte)(nil)) | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// offsetPtr, offsetScalar, and offsetFlag are the offsets for the | ||||
| 	// internal reflect.Value fields.  These values are valid before golang | ||||
| 	// commit ecccf07e7f9d which changed the format.  The are also valid | ||||
| 	// after commit 82f48826c6c7 which changed the format again to mirror | ||||
| 	// the original format.  Code in the init function updates these offsets | ||||
| 	// as necessary. | ||||
| 	offsetPtr    = uintptr(ptrSize) | ||||
| 	offsetScalar = uintptr(0) | ||||
| 	offsetFlag   = uintptr(ptrSize * 2) | ||||
| type flag uintptr | ||||
|  | ||||
| 	// flagKindWidth and flagKindShift indicate various bits that the | ||||
| 	// reflect package uses internally to track kind information. | ||||
| 	// | ||||
| 	// flagRO indicates whether or not the value field of a reflect.Value is | ||||
| 	// read-only. | ||||
| 	// | ||||
| 	// flagIndir indicates whether the value field of a reflect.Value is | ||||
| 	// the actual data or a pointer to the data. | ||||
| 	// | ||||
| 	// These values are valid before golang commit 90a7c3c86944 which | ||||
| 	// changed their positions.  Code in the init function updates these | ||||
| 	// flags as necessary. | ||||
| 	flagKindWidth = uintptr(5) | ||||
| 	flagKindShift = uintptr(flagKindWidth - 1) | ||||
| 	flagRO        = uintptr(1 << 0) | ||||
| 	flagIndir     = uintptr(1 << 1) | ||||
| var ( | ||||
| 	// flagRO indicates whether the value field of a reflect.Value | ||||
| 	// is read-only. | ||||
| 	flagRO flag | ||||
|  | ||||
| 	// flagAddr indicates whether the address of the reflect.Value's | ||||
| 	// value may be taken. | ||||
| 	flagAddr flag | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	// Older versions of reflect.Value stored small integers directly in the | ||||
| 	// ptr field (which is named val in the older versions).  Versions | ||||
| 	// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named | ||||
| 	// scalar for this purpose which unfortunately came before the flag | ||||
| 	// field, so the offset of the flag field is different for those | ||||
| 	// versions. | ||||
| 	// | ||||
| 	// This code constructs a new reflect.Value from a known small integer | ||||
| 	// and checks if the size of the reflect.Value struct indicates it has | ||||
| 	// the scalar field. When it does, the offsets are updated accordingly. | ||||
| 	vv := reflect.ValueOf(0xf00) | ||||
| 	if unsafe.Sizeof(vv) == (ptrSize * 4) { | ||||
| 		offsetScalar = ptrSize * 2 | ||||
| 		offsetFlag = ptrSize * 3 | ||||
| 	} | ||||
| // flagKindMask holds the bits that make up the kind | ||||
| // part of the flags field. In all the supported versions, | ||||
| // it is in the lower 5 bits. | ||||
| const flagKindMask = flag(0x1f) | ||||
|  | ||||
| 	// Commit 90a7c3c86944 changed the flag positions such that the low | ||||
| 	// order bits are the kind.  This code extracts the kind from the flags | ||||
| 	// field and ensures it's the correct type.  When it's not, the flag | ||||
| 	// order has been changed to the newer format, so the flags are updated | ||||
| 	// accordingly. | ||||
| 	upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) | ||||
| 	upfv := *(*uintptr)(upf) | ||||
| 	flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift) | ||||
| 	if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) { | ||||
| 		flagKindShift = 0 | ||||
| 		flagRO = 1 << 5 | ||||
| 		flagIndir = 1 << 6 | ||||
| // Different versions of Go have used different | ||||
| // bit layouts for the flags type. This table | ||||
| // records the known combinations. | ||||
| var okFlags = []struct { | ||||
| 	ro, addr flag | ||||
| }{{ | ||||
| 	// From Go 1.4 to 1.5 | ||||
| 	ro:   1 << 5, | ||||
| 	addr: 1 << 7, | ||||
| }, { | ||||
| 	// Up to Go tip. | ||||
| 	ro:   1<<5 | 1<<6, | ||||
| 	addr: 1 << 8, | ||||
| }} | ||||
|  | ||||
| 		// Commit adf9b30e5594 modified the flags to separate the | ||||
| 		// flagRO flag into two bits which specifies whether or not the | ||||
| 		// field is embedded.  This causes flagIndir to move over a bit | ||||
| 		// and means that flagRO is the combination of either of the | ||||
| 		// original flagRO bit and the new bit. | ||||
| 		// | ||||
| 		// This code detects the change by extracting what used to be | ||||
| 		// the indirect bit to ensure it's set.  When it's not, the flag | ||||
| 		// order has been changed to the newer format, so the flags are | ||||
| 		// updated accordingly. | ||||
| 		if upfv&flagIndir == 0 { | ||||
| 			flagRO = 3 << 5 | ||||
| 			flagIndir = 1 << 7 | ||||
| 		} | ||||
| var flagValOffset = func() uintptr { | ||||
| 	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") | ||||
| 	if !ok { | ||||
| 		panic("reflect.Value has no flag field") | ||||
| 	} | ||||
| 	return field.Offset | ||||
| }() | ||||
|  | ||||
| // flagField returns a pointer to the flag field of a reflect.Value. | ||||
| func flagField(v *reflect.Value) *flag { | ||||
| 	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) | ||||
| } | ||||
|  | ||||
| // unsafeReflectValue converts the passed reflect.Value into a one that bypasses | ||||
| @@ -119,34 +90,56 @@ func init() { | ||||
| // This allows us to check for implementations of the Stringer and error | ||||
| // interfaces to be used for pretty printing ordinarily unaddressable and | ||||
| // inaccessible values such as unexported struct fields. | ||||
| func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { | ||||
| 	indirects := 1 | ||||
| 	vt := v.Type() | ||||
| 	upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) | ||||
| 	rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) | ||||
| 	if rvf&flagIndir != 0 { | ||||
| 		vt = reflect.PtrTo(v.Type()) | ||||
| 		indirects++ | ||||
| 	} else if offsetScalar != 0 { | ||||
| 		// The value is in the scalar field when it's not one of the | ||||
| 		// reference types. | ||||
| 		switch vt.Kind() { | ||||
| 		case reflect.Uintptr: | ||||
| 		case reflect.Chan: | ||||
| 		case reflect.Func: | ||||
| 		case reflect.Map: | ||||
| 		case reflect.Ptr: | ||||
| 		case reflect.UnsafePointer: | ||||
| 		default: | ||||
| 			upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + | ||||
| 				offsetScalar) | ||||
| func unsafeReflectValue(v reflect.Value) reflect.Value { | ||||
| 	if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { | ||||
| 		return v | ||||
| 	} | ||||
| 	flagFieldPtr := flagField(&v) | ||||
| 	*flagFieldPtr &^= flagRO | ||||
| 	*flagFieldPtr |= flagAddr | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| 	pv := reflect.NewAt(vt, upv) | ||||
| 	rv = pv | ||||
| 	for i := 0; i < indirects; i++ { | ||||
| 		rv = rv.Elem() | ||||
| // Sanity checks against future reflect package changes | ||||
| // to the type or semantics of the Value.flag field. | ||||
| func init() { | ||||
| 	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") | ||||
| 	if !ok { | ||||
| 		panic("reflect.Value has no flag field") | ||||
| 	} | ||||
| 	return rv | ||||
| 	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { | ||||
| 		panic("reflect.Value flag field has changed kind") | ||||
| 	} | ||||
| 	type t0 int | ||||
| 	var t struct { | ||||
| 		A t0 | ||||
| 		// t0 will have flagEmbedRO set. | ||||
| 		t0 | ||||
| 		// a will have flagStickyRO set | ||||
| 		a t0 | ||||
| 	} | ||||
| 	vA := reflect.ValueOf(t).FieldByName("A") | ||||
| 	va := reflect.ValueOf(t).FieldByName("a") | ||||
| 	vt0 := reflect.ValueOf(t).FieldByName("t0") | ||||
|  | ||||
| 	// Infer flagRO from the difference between the flags | ||||
| 	// for the (otherwise identical) fields in t. | ||||
| 	flagPublic := *flagField(&vA) | ||||
| 	flagWithRO := *flagField(&va) | *flagField(&vt0) | ||||
| 	flagRO = flagPublic ^ flagWithRO | ||||
|  | ||||
| 	// Infer flagAddr from the difference between a value | ||||
| 	// taken from a pointer and not. | ||||
| 	vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") | ||||
| 	flagNoPtr := *flagField(&vA) | ||||
| 	flagPtr := *flagField(&vPtrA) | ||||
| 	flagAddr = flagNoPtr ^ flagPtr | ||||
|  | ||||
| 	// Check that the inferred flags tally with one of the known versions. | ||||
| 	for _, f := range okFlags { | ||||
| 		if flagRO == f.ro && flagAddr == f.addr { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	panic("reflect.Value read-only flag has changed semantics") | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -16,7 +16,7 @@ | ||||
| // when the code is running on Google App Engine, compiled by GopherJS, or | ||||
| // "-tags safe" is added to the go build command line.  The "disableunsafe" | ||||
| // tag is deprecated and thus should not be used. | ||||
| // +build js appengine safe disableunsafe | ||||
| // +build js appengine safe disableunsafe !go1.4 | ||||
|  | ||||
| package spew | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/davecgh/go-spew/spew/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/davecgh/go-spew/spew/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) { | ||||
| 	w.Write(closeParenBytes) | ||||
| } | ||||
|  | ||||
| // printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' | ||||
| // printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' | ||||
| // prefix to Writer w. | ||||
| func printHexPtr(w io.Writer, p uintptr) { | ||||
| 	// Null pointer. | ||||
|   | ||||
							
								
								
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/davecgh/go-spew/spew/dump.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -35,16 +35,16 @@ var ( | ||||
|  | ||||
| 	// cCharRE is a regular expression that matches a cgo char. | ||||
| 	// It is used to detect character arrays to hexdump them. | ||||
| 	cCharRE = regexp.MustCompile("^.*\\._Ctype_char$") | ||||
| 	cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) | ||||
|  | ||||
| 	// cUnsignedCharRE is a regular expression that matches a cgo unsigned | ||||
| 	// char.  It is used to detect unsigned character arrays to hexdump | ||||
| 	// them. | ||||
| 	cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$") | ||||
| 	cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) | ||||
|  | ||||
| 	// cUint8tCharRE is a regular expression that matches a cgo uint8_t. | ||||
| 	// It is used to detect uint8_t arrays to hexdump them. | ||||
| 	cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$") | ||||
| 	cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) | ||||
| ) | ||||
|  | ||||
| // dumpState contains information about the state of a dump operation. | ||||
| @@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) { | ||||
| 	// Display dereferenced value. | ||||
| 	d.w.Write(openParenBytes) | ||||
| 	switch { | ||||
| 	case nilFound == true: | ||||
| 	case nilFound: | ||||
| 		d.w.Write(nilAngleBytes) | ||||
|  | ||||
| 	case cycleFound == true: | ||||
| 	case cycleFound: | ||||
| 		d.w.Write(circularBytes) | ||||
|  | ||||
| 	default: | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/davecgh/go-spew/spew/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/davecgh/go-spew/spew/format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) { | ||||
|  | ||||
| 	// Display dereferenced value. | ||||
| 	switch { | ||||
| 	case nilFound == true: | ||||
| 	case nilFound: | ||||
| 		f.fs.Write(nilAngleBytes) | ||||
|  | ||||
| 	case cycleFound == true: | ||||
| 	case cycleFound: | ||||
| 		f.fs.Write(circularShortBytes) | ||||
|  | ||||
| 	default: | ||||
|   | ||||
							
								
								
									
										36
									
								
								vendor/github.com/disintegration/imaging/effects.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/disintegration/imaging/effects.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -38,9 +38,13 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA { | ||||
|  | ||||
| 	parallel(0, src.h, func(ys <-chan int) { | ||||
| 		scanLine := make([]uint8, src.w*4) | ||||
| 		scanLineF := make([]float64, len(scanLine)) | ||||
| 		for y := range ys { | ||||
| 			src.scan(0, y, src.w, y+1, scanLine) | ||||
| 			for x := 0; x < src.w; x++ { | ||||
| 			for i, v := range scanLine { | ||||
| 				scanLineF[i] = float64(v) | ||||
| 			} | ||||
| 			for x, idx := 0, 0; x < src.w; x, idx = x+1, idx+4 { | ||||
| 				min := x - radius | ||||
| 				if min < 0 { | ||||
| 					min = 0 | ||||
| @@ -55,10 +59,10 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA { | ||||
| 					i := ix * 4 | ||||
| 					weight := kernel[absint(x-ix)] | ||||
| 					wsum += weight | ||||
| 					wa := float64(scanLine[i+3]) * weight | ||||
| 					r += float64(scanLine[i+0]) * wa | ||||
| 					g += float64(scanLine[i+1]) * wa | ||||
| 					b += float64(scanLine[i+2]) * wa | ||||
| 					wa := scanLineF[i+3] * weight | ||||
| 					r += scanLineF[i+0] * wa | ||||
| 					g += scanLineF[i+1] * wa | ||||
| 					b += scanLineF[i+2] * wa | ||||
| 					a += wa | ||||
| 				} | ||||
| 				if a != 0 { | ||||
| @@ -67,12 +71,12 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA { | ||||
| 					b /= a | ||||
| 				} | ||||
|  | ||||
| 				j := y*dst.Stride + x*4 | ||||
| 				dst.Pix[j+0] = clamp(r) | ||||
| 				dst.Pix[j+1] = clamp(g) | ||||
| 				dst.Pix[j+2] = clamp(b) | ||||
| 				dst.Pix[j+3] = clamp(a / wsum) | ||||
| 				scanLine[idx+0] = clamp(r) | ||||
| 				scanLine[idx+1] = clamp(g) | ||||
| 				scanLine[idx+2] = clamp(b) | ||||
| 				scanLine[idx+3] = clamp(a / wsum) | ||||
| 			} | ||||
| 			copy(dst.Pix[y*dst.Stride:], scanLine) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| @@ -86,8 +90,12 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA { | ||||
|  | ||||
| 	parallel(0, src.w, func(xs <-chan int) { | ||||
| 		scanLine := make([]uint8, src.h*4) | ||||
| 		scanLineF := make([]float64, len(scanLine)) | ||||
| 		for x := range xs { | ||||
| 			src.scan(x, 0, x+1, src.h, scanLine) | ||||
| 			for i, v := range scanLine { | ||||
| 				scanLineF[i] = float64(v) | ||||
| 			} | ||||
| 			for y := 0; y < src.h; y++ { | ||||
| 				min := y - radius | ||||
| 				if min < 0 { | ||||
| @@ -103,10 +111,10 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA { | ||||
| 					i := iy * 4 | ||||
| 					weight := kernel[absint(y-iy)] | ||||
| 					wsum += weight | ||||
| 					wa := float64(scanLine[i+3]) * weight | ||||
| 					r += float64(scanLine[i+0]) * wa | ||||
| 					g += float64(scanLine[i+1]) * wa | ||||
| 					b += float64(scanLine[i+2]) * wa | ||||
| 					wa := scanLineF[i+3] * weight | ||||
| 					r += scanLineF[i+0] * wa | ||||
| 					g += scanLineF[i+1] * wa | ||||
| 					b += scanLineF[i+2] * wa | ||||
| 					a += wa | ||||
| 				} | ||||
| 				if a != 0 { | ||||
|   | ||||
							
								
								
									
										272
									
								
								vendor/github.com/disintegration/imaging/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										272
									
								
								vendor/github.com/disintegration/imaging/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,272 +0,0 @@ | ||||
| package imaging | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"image" | ||||
| 	"image/color" | ||||
| 	"image/draw" | ||||
| 	"image/gif" | ||||
| 	"image/jpeg" | ||||
| 	"image/png" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	"golang.org/x/image/bmp" | ||||
| 	"golang.org/x/image/tiff" | ||||
| ) | ||||
|  | ||||
| // Format is an image file format. | ||||
| type Format int | ||||
|  | ||||
| // Image file formats. | ||||
| const ( | ||||
| 	JPEG Format = iota | ||||
| 	PNG | ||||
| 	GIF | ||||
| 	TIFF | ||||
| 	BMP | ||||
| ) | ||||
|  | ||||
| func (f Format) String() string { | ||||
| 	switch f { | ||||
| 	case JPEG: | ||||
| 		return "JPEG" | ||||
| 	case PNG: | ||||
| 		return "PNG" | ||||
| 	case GIF: | ||||
| 		return "GIF" | ||||
| 	case TIFF: | ||||
| 		return "TIFF" | ||||
| 	case BMP: | ||||
| 		return "BMP" | ||||
| 	default: | ||||
| 		return "Unsupported" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var formatFromExt = map[string]Format{ | ||||
| 	".jpg":  JPEG, | ||||
| 	".jpeg": JPEG, | ||||
| 	".png":  PNG, | ||||
| 	".tif":  TIFF, | ||||
| 	".tiff": TIFF, | ||||
| 	".bmp":  BMP, | ||||
| 	".gif":  GIF, | ||||
| } | ||||
|  | ||||
| // FormatFromFilename parses image format from filename extension: | ||||
| // "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. | ||||
| func FormatFromFilename(filename string) (Format, error) { | ||||
| 	ext := strings.ToLower(filepath.Ext(filename)) | ||||
| 	if f, ok := formatFromExt[ext]; ok { | ||||
| 		return f, nil | ||||
| 	} | ||||
| 	return -1, ErrUnsupportedFormat | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// ErrUnsupportedFormat means the given image format (or file extension) is unsupported. | ||||
| 	ErrUnsupportedFormat = errors.New("imaging: unsupported image format") | ||||
| ) | ||||
|  | ||||
| type fileSystem interface { | ||||
| 	Create(string) (io.WriteCloser, error) | ||||
| 	Open(string) (io.ReadCloser, error) | ||||
| } | ||||
|  | ||||
| type localFS struct{} | ||||
|  | ||||
| func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) } | ||||
| func (localFS) Open(name string) (io.ReadCloser, error)    { return os.Open(name) } | ||||
|  | ||||
| var fs fileSystem = localFS{} | ||||
|  | ||||
| // Decode reads an image from r. | ||||
| func Decode(r io.Reader) (image.Image, error) { | ||||
| 	img, _, err := image.Decode(r) | ||||
| 	return img, err | ||||
| } | ||||
|  | ||||
| // Open loads an image from file | ||||
| func Open(filename string) (image.Image, error) { | ||||
| 	file, err := fs.Open(filename) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
| 	return Decode(file) | ||||
| } | ||||
|  | ||||
| type encodeConfig struct { | ||||
| 	jpegQuality         int | ||||
| 	gifNumColors        int | ||||
| 	gifQuantizer        draw.Quantizer | ||||
| 	gifDrawer           draw.Drawer | ||||
| 	pngCompressionLevel png.CompressionLevel | ||||
| } | ||||
|  | ||||
| var defaultEncodeConfig = encodeConfig{ | ||||
| 	jpegQuality:         95, | ||||
| 	gifNumColors:        256, | ||||
| 	gifQuantizer:        nil, | ||||
| 	gifDrawer:           nil, | ||||
| 	pngCompressionLevel: png.DefaultCompression, | ||||
| } | ||||
|  | ||||
| // EncodeOption sets an optional parameter for the Encode and Save functions. | ||||
| type EncodeOption func(*encodeConfig) | ||||
|  | ||||
| // JPEGQuality returns an EncodeOption that sets the output JPEG quality. | ||||
| // Quality ranges from 1 to 100 inclusive, higher is better. Default is 95. | ||||
| func JPEGQuality(quality int) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.jpegQuality = quality | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFNumColors returns an EncodeOption that sets the maximum number of colors | ||||
| // used in the GIF-encoded image. It ranges from 1 to 256.  Default is 256. | ||||
| func GIFNumColors(numColors int) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifNumColors = numColors | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce | ||||
| // a palette of the GIF-encoded image. | ||||
| func GIFQuantizer(quantizer draw.Quantizer) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifQuantizer = quantizer | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFDrawer returns an EncodeOption that sets the drawer that is used to convert | ||||
| // the source image to the desired palette of the GIF-encoded image. | ||||
| func GIFDrawer(drawer draw.Drawer) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifDrawer = drawer | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // PNGCompressionLevel returns an EncodeOption that sets the compression level | ||||
| // of the PNG-encoded image. Default is png.DefaultCompression. | ||||
| func PNGCompressionLevel(level png.CompressionLevel) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.pngCompressionLevel = level | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP). | ||||
| func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error { | ||||
| 	cfg := defaultEncodeConfig | ||||
| 	for _, option := range opts { | ||||
| 		option(&cfg) | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	switch format { | ||||
| 	case JPEG: | ||||
| 		var rgba *image.RGBA | ||||
| 		if nrgba, ok := img.(*image.NRGBA); ok { | ||||
| 			if nrgba.Opaque() { | ||||
| 				rgba = &image.RGBA{ | ||||
| 					Pix:    nrgba.Pix, | ||||
| 					Stride: nrgba.Stride, | ||||
| 					Rect:   nrgba.Rect, | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if rgba != nil { | ||||
| 			err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality}) | ||||
| 		} else { | ||||
| 			err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality}) | ||||
| 		} | ||||
|  | ||||
| 	case PNG: | ||||
| 		enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel} | ||||
| 		err = enc.Encode(w, img) | ||||
|  | ||||
| 	case GIF: | ||||
| 		err = gif.Encode(w, img, &gif.Options{ | ||||
| 			NumColors: cfg.gifNumColors, | ||||
| 			Quantizer: cfg.gifQuantizer, | ||||
| 			Drawer:    cfg.gifDrawer, | ||||
| 		}) | ||||
|  | ||||
| 	case TIFF: | ||||
| 		err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true}) | ||||
|  | ||||
| 	case BMP: | ||||
| 		err = bmp.Encode(w, img) | ||||
|  | ||||
| 	default: | ||||
| 		err = ErrUnsupportedFormat | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Save saves the image to file with the specified filename. | ||||
| // The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| //	// Save the image as PNG. | ||||
| //	err := imaging.Save(img, "out.png") | ||||
| // | ||||
| //	// Save the image as JPEG with optional quality parameter set to 80. | ||||
| //	err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80)) | ||||
| // | ||||
| func Save(img image.Image, filename string, opts ...EncodeOption) (err error) { | ||||
| 	f, err := FormatFromFilename(filename) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	file, err := fs.Create(filename) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	defer func() { | ||||
| 		cerr := file.Close() | ||||
| 		if err == nil { | ||||
| 			err = cerr | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return Encode(file, img, f, opts...) | ||||
| } | ||||
|  | ||||
| // New creates a new image with the specified width and height, and fills it with the specified color. | ||||
| func New(width, height int, fillColor color.Color) *image.NRGBA { | ||||
| 	if width <= 0 || height <= 0 { | ||||
| 		return &image.NRGBA{} | ||||
| 	} | ||||
|  | ||||
| 	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA) | ||||
| 	if (c == color.NRGBA{0, 0, 0, 0}) { | ||||
| 		return image.NewNRGBA(image.Rect(0, 0, width, height)) | ||||
| 	} | ||||
|  | ||||
| 	return &image.NRGBA{ | ||||
| 		Pix:    bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height), | ||||
| 		Stride: 4 * width, | ||||
| 		Rect:   image.Rect(0, 0, width, height), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Clone returns a copy of the given image. | ||||
| func Clone(img image.Image) *image.NRGBA { | ||||
| 	src := newScanner(img) | ||||
| 	dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h)) | ||||
| 	size := src.w * 4 | ||||
| 	parallel(0, src.h, func(ys <-chan int) { | ||||
| 		for y := range ys { | ||||
| 			i := y * dst.Stride | ||||
| 			src.scan(0, y, src.w, y+1, dst.Pix[i:i+size]) | ||||
| 		} | ||||
| 	}) | ||||
| 	return dst | ||||
| } | ||||
							
								
								
									
										463
									
								
								vendor/github.com/disintegration/imaging/io.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										463
									
								
								vendor/github.com/disintegration/imaging/io.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,463 @@ | ||||
| package imaging | ||||
|  | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"image" | ||||
| 	"image/draw" | ||||
| 	"image/gif" | ||||
| 	"image/jpeg" | ||||
| 	"image/png" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	"golang.org/x/image/bmp" | ||||
| 	"golang.org/x/image/tiff" | ||||
| ) | ||||
|  | ||||
| // Format is an image file format. | ||||
| type Format int | ||||
|  | ||||
| // Image file formats. | ||||
| const ( | ||||
| 	JPEG Format = iota | ||||
| 	PNG | ||||
| 	GIF | ||||
| 	TIFF | ||||
| 	BMP | ||||
| ) | ||||
|  | ||||
| func (f Format) String() string { | ||||
| 	switch f { | ||||
| 	case JPEG: | ||||
| 		return "JPEG" | ||||
| 	case PNG: | ||||
| 		return "PNG" | ||||
| 	case GIF: | ||||
| 		return "GIF" | ||||
| 	case TIFF: | ||||
| 		return "TIFF" | ||||
| 	case BMP: | ||||
| 		return "BMP" | ||||
| 	default: | ||||
| 		return "Unsupported" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var formatFromExt = map[string]Format{ | ||||
| 	"jpg":  JPEG, | ||||
| 	"jpeg": JPEG, | ||||
| 	"png":  PNG, | ||||
| 	"tif":  TIFF, | ||||
| 	"tiff": TIFF, | ||||
| 	"bmp":  BMP, | ||||
| 	"gif":  GIF, | ||||
| } | ||||
|  | ||||
| // FormatFromExtension parses image format from extension: | ||||
| // "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. | ||||
| func FormatFromExtension(ext string) (Format, error) { | ||||
| 	if f, ok := formatFromExt[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok { | ||||
| 		return f, nil | ||||
| 	} | ||||
| 	return -1, ErrUnsupportedFormat | ||||
| } | ||||
|  | ||||
| // FormatFromFilename parses image format from filename extension: | ||||
| // "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. | ||||
| func FormatFromFilename(filename string) (Format, error) { | ||||
| 	ext := filepath.Ext(filename) | ||||
| 	return FormatFromExtension(ext) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// ErrUnsupportedFormat means the given image format (or file extension) is unsupported. | ||||
| 	ErrUnsupportedFormat = errors.New("imaging: unsupported image format") | ||||
| ) | ||||
|  | ||||
| type fileSystem interface { | ||||
| 	Create(string) (io.WriteCloser, error) | ||||
| 	Open(string) (io.ReadCloser, error) | ||||
| } | ||||
|  | ||||
| type localFS struct{} | ||||
|  | ||||
| func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) } | ||||
| func (localFS) Open(name string) (io.ReadCloser, error)    { return os.Open(name) } | ||||
|  | ||||
| var fs fileSystem = localFS{} | ||||
|  | ||||
| type decodeConfig struct { | ||||
| 	autoOrientation bool | ||||
| } | ||||
|  | ||||
| var defaultDecodeConfig = decodeConfig{ | ||||
| 	autoOrientation: false, | ||||
| } | ||||
|  | ||||
| // DecodeOption sets an optional parameter for the Decode and Open functions. | ||||
| type DecodeOption func(*decodeConfig) | ||||
|  | ||||
| // AutoOrientation returns a DecodeOption that sets the auto-orientation mode. | ||||
| // If auto-orientation is enabled, the image will be transformed after decoding | ||||
| // according to the EXIF orientation tag (if present). By default it's disabled. | ||||
| func AutoOrientation(enabled bool) DecodeOption { | ||||
| 	return func(c *decodeConfig) { | ||||
| 		c.autoOrientation = enabled | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Decode reads an image from r. | ||||
| func Decode(r io.Reader, opts ...DecodeOption) (image.Image, error) { | ||||
| 	cfg := defaultDecodeConfig | ||||
| 	for _, option := range opts { | ||||
| 		option(&cfg) | ||||
| 	} | ||||
|  | ||||
| 	if !cfg.autoOrientation { | ||||
| 		img, _, err := image.Decode(r) | ||||
| 		return img, err | ||||
| 	} | ||||
|  | ||||
| 	var orient orientation | ||||
| 	pr, pw := io.Pipe() | ||||
| 	r = io.TeeReader(r, pw) | ||||
| 	done := make(chan struct{}) | ||||
| 	go func() { | ||||
| 		defer close(done) | ||||
| 		orient = readOrientation(pr) | ||||
| 		io.Copy(ioutil.Discard, pr) | ||||
| 	}() | ||||
|  | ||||
| 	img, _, err := image.Decode(r) | ||||
| 	pw.Close() | ||||
| 	<-done | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return fixOrientation(img, orient), nil | ||||
| } | ||||
|  | ||||
| // Open loads an image from file. | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| //	// Load an image from file. | ||||
| //	img, err := imaging.Open("test.jpg") | ||||
| // | ||||
| //	// Load an image and transform it depending on the EXIF orientation tag (if present). | ||||
| //	img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true)) | ||||
| // | ||||
| func Open(filename string, opts ...DecodeOption) (image.Image, error) { | ||||
| 	file, err := fs.Open(filename) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
| 	return Decode(file, opts...) | ||||
| } | ||||
|  | ||||
| type encodeConfig struct { | ||||
| 	jpegQuality         int | ||||
| 	gifNumColors        int | ||||
| 	gifQuantizer        draw.Quantizer | ||||
| 	gifDrawer           draw.Drawer | ||||
| 	pngCompressionLevel png.CompressionLevel | ||||
| } | ||||
|  | ||||
| var defaultEncodeConfig = encodeConfig{ | ||||
| 	jpegQuality:         95, | ||||
| 	gifNumColors:        256, | ||||
| 	gifQuantizer:        nil, | ||||
| 	gifDrawer:           nil, | ||||
| 	pngCompressionLevel: png.DefaultCompression, | ||||
| } | ||||
|  | ||||
| // EncodeOption sets an optional parameter for the Encode and Save functions. | ||||
| type EncodeOption func(*encodeConfig) | ||||
|  | ||||
| // JPEGQuality returns an EncodeOption that sets the output JPEG quality. | ||||
| // Quality ranges from 1 to 100 inclusive, higher is better. Default is 95. | ||||
| func JPEGQuality(quality int) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.jpegQuality = quality | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFNumColors returns an EncodeOption that sets the maximum number of colors | ||||
| // used in the GIF-encoded image. It ranges from 1 to 256.  Default is 256. | ||||
| func GIFNumColors(numColors int) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifNumColors = numColors | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce | ||||
| // a palette of the GIF-encoded image. | ||||
| func GIFQuantizer(quantizer draw.Quantizer) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifQuantizer = quantizer | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GIFDrawer returns an EncodeOption that sets the drawer that is used to convert | ||||
| // the source image to the desired palette of the GIF-encoded image. | ||||
| func GIFDrawer(drawer draw.Drawer) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.gifDrawer = drawer | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // PNGCompressionLevel returns an EncodeOption that sets the compression level | ||||
| // of the PNG-encoded image. Default is png.DefaultCompression. | ||||
| func PNGCompressionLevel(level png.CompressionLevel) EncodeOption { | ||||
| 	return func(c *encodeConfig) { | ||||
| 		c.pngCompressionLevel = level | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP). | ||||
| func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error { | ||||
| 	cfg := defaultEncodeConfig | ||||
| 	for _, option := range opts { | ||||
| 		option(&cfg) | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	switch format { | ||||
| 	case JPEG: | ||||
| 		var rgba *image.RGBA | ||||
| 		if nrgba, ok := img.(*image.NRGBA); ok { | ||||
| 			if nrgba.Opaque() { | ||||
| 				rgba = &image.RGBA{ | ||||
| 					Pix:    nrgba.Pix, | ||||
| 					Stride: nrgba.Stride, | ||||
| 					Rect:   nrgba.Rect, | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if rgba != nil { | ||||
| 			err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality}) | ||||
| 		} else { | ||||
| 			err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality}) | ||||
| 		} | ||||
|  | ||||
| 	case PNG: | ||||
| 		enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel} | ||||
| 		err = enc.Encode(w, img) | ||||
|  | ||||
| 	case GIF: | ||||
| 		err = gif.Encode(w, img, &gif.Options{ | ||||
| 			NumColors: cfg.gifNumColors, | ||||
| 			Quantizer: cfg.gifQuantizer, | ||||
| 			Drawer:    cfg.gifDrawer, | ||||
| 		}) | ||||
|  | ||||
| 	case TIFF: | ||||
| 		err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true}) | ||||
|  | ||||
| 	case BMP: | ||||
| 		err = bmp.Encode(w, img) | ||||
|  | ||||
| 	default: | ||||
| 		err = ErrUnsupportedFormat | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Save saves the image to file with the specified filename. | ||||
| // The format is determined from the filename extension: | ||||
| // "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. | ||||
| // | ||||
| // Examples: | ||||
| // | ||||
| //	// Save the image as PNG. | ||||
| //	err := imaging.Save(img, "out.png") | ||||
| // | ||||
| //	// Save the image as JPEG with optional quality parameter set to 80. | ||||
| //	err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80)) | ||||
| // | ||||
| func Save(img image.Image, filename string, opts ...EncodeOption) (err error) { | ||||
| 	f, err := FormatFromFilename(filename) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	file, err := fs.Create(filename) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	defer func() { | ||||
| 		cerr := file.Close() | ||||
| 		if err == nil { | ||||
| 			err = cerr | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return Encode(file, img, f, opts...) | ||||
| } | ||||
|  | ||||
| // orientation is an EXIF flag that specifies the transformation | ||||
| // that should be applied to image to display it correctly. | ||||
| type orientation int | ||||
|  | ||||
| const ( | ||||
| 	orientationUnspecified = 0 | ||||
| 	orientationNormal      = 1 | ||||
| 	orientationFlipH       = 2 | ||||
| 	orientationRotate180   = 3 | ||||
| 	orientationFlipV       = 4 | ||||
| 	orientationTranspose   = 5 | ||||
| 	orientationRotate270   = 6 | ||||
| 	orientationTransverse  = 7 | ||||
| 	orientationRotate90    = 8 | ||||
| ) | ||||
|  | ||||
| // readOrientation tries to read the orientation EXIF flag from image data in r. | ||||
| // If the EXIF data block is not found or the orientation flag is not found | ||||
| // or any other error occures while reading the data, it returns the | ||||
| // orientationUnspecified (0) value. | ||||
| func readOrientation(r io.Reader) orientation { | ||||
| 	const ( | ||||
| 		markerSOI      = 0xffd8 | ||||
| 		markerAPP1     = 0xffe1 | ||||
| 		exifHeader     = 0x45786966 | ||||
| 		byteOrderBE    = 0x4d4d | ||||
| 		byteOrderLE    = 0x4949 | ||||
| 		orientationTag = 0x0112 | ||||
| 	) | ||||
|  | ||||
| 	// Check if JPEG SOI marker is present. | ||||
| 	var soi uint16 | ||||
| 	if err := binary.Read(r, binary.BigEndian, &soi); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
| 	if soi != markerSOI { | ||||
| 		return orientationUnspecified // Missing JPEG SOI marker. | ||||
| 	} | ||||
|  | ||||
| 	// Find JPEG APP1 marker. | ||||
| 	for { | ||||
| 		var marker, size uint16 | ||||
| 		if err := binary.Read(r, binary.BigEndian, &marker); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 		if err := binary.Read(r, binary.BigEndian, &size); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 		if marker>>8 != 0xff { | ||||
| 			return orientationUnspecified // Invalid JPEG marker. | ||||
| 		} | ||||
| 		if marker == markerAPP1 { | ||||
| 			break | ||||
| 		} | ||||
| 		if size < 2 { | ||||
| 			return orientationUnspecified // Invalid block size. | ||||
| 		} | ||||
| 		if _, err := io.CopyN(ioutil.Discard, r, int64(size-2)); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Check if EXIF header is present. | ||||
| 	var header uint32 | ||||
| 	if err := binary.Read(r, binary.BigEndian, &header); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
| 	if header != exifHeader { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
| 	if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
|  | ||||
| 	// Read byte order information. | ||||
| 	var ( | ||||
| 		byteOrderTag uint16 | ||||
| 		byteOrder    binary.ByteOrder | ||||
| 	) | ||||
| 	if err := binary.Read(r, binary.BigEndian, &byteOrderTag); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
| 	switch byteOrderTag { | ||||
| 	case byteOrderBE: | ||||
| 		byteOrder = binary.BigEndian | ||||
| 	case byteOrderLE: | ||||
| 		byteOrder = binary.LittleEndian | ||||
| 	default: | ||||
| 		return orientationUnspecified // Invalid byte order flag. | ||||
| 	} | ||||
| 	if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
|  | ||||
| 	// Skip the EXIF offset. | ||||
| 	var offset uint32 | ||||
| 	if err := binary.Read(r, byteOrder, &offset); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
| 	if offset < 8 { | ||||
| 		return orientationUnspecified // Invalid offset value. | ||||
| 	} | ||||
| 	if _, err := io.CopyN(ioutil.Discard, r, int64(offset-8)); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
|  | ||||
| 	// Read the number of tags. | ||||
| 	var numTags uint16 | ||||
| 	if err := binary.Read(r, byteOrder, &numTags); err != nil { | ||||
| 		return orientationUnspecified | ||||
| 	} | ||||
|  | ||||
| 	// Find the orientation tag. | ||||
| 	for i := 0; i < int(numTags); i++ { | ||||
| 		var tag uint16 | ||||
| 		if err := binary.Read(r, byteOrder, &tag); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 		if tag != orientationTag { | ||||
| 			if _, err := io.CopyN(ioutil.Discard, r, 10); err != nil { | ||||
| 				return orientationUnspecified | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if _, err := io.CopyN(ioutil.Discard, r, 6); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 		var val uint16 | ||||
| 		if err := binary.Read(r, byteOrder, &val); err != nil { | ||||
| 			return orientationUnspecified | ||||
| 		} | ||||
| 		if val < 1 || val > 8 { | ||||
| 			return orientationUnspecified // Invalid tag value. | ||||
| 		} | ||||
| 		return orientation(val) | ||||
| 	} | ||||
| 	return orientationUnspecified // Missing orientation tag. | ||||
| } | ||||
|  | ||||
| // fixOrientation applies a transform to img corresponding to the given orientation flag. | ||||
| func fixOrientation(img image.Image, o orientation) image.Image { | ||||
| 	switch o { | ||||
| 	case orientationNormal: | ||||
| 	case orientationFlipH: | ||||
| 		img = FlipH(img) | ||||
| 	case orientationFlipV: | ||||
| 		img = FlipV(img) | ||||
| 	case orientationRotate90: | ||||
| 		img = Rotate90(img) | ||||
| 	case orientationRotate180: | ||||
| 		img = Rotate180(img) | ||||
| 	case orientationRotate270: | ||||
| 		img = Rotate270(img) | ||||
| 	case orientationTranspose: | ||||
| 		img = Transpose(img) | ||||
| 	case orientationTransverse: | ||||
| 		img = Transverse(img) | ||||
| 	} | ||||
| 	return img | ||||
| } | ||||
							
								
								
									
										34
									
								
								vendor/github.com/disintegration/imaging/tools.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/disintegration/imaging/tools.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,10 +1,44 @@ | ||||
| package imaging | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"image" | ||||
| 	"image/color" | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| // New creates a new image with the specified width and height, and fills it with the specified color. | ||||
| func New(width, height int, fillColor color.Color) *image.NRGBA { | ||||
| 	if width <= 0 || height <= 0 { | ||||
| 		return &image.NRGBA{} | ||||
| 	} | ||||
|  | ||||
| 	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA) | ||||
| 	if (c == color.NRGBA{0, 0, 0, 0}) { | ||||
| 		return image.NewNRGBA(image.Rect(0, 0, width, height)) | ||||
| 	} | ||||
|  | ||||
| 	return &image.NRGBA{ | ||||
| 		Pix:    bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height), | ||||
| 		Stride: 4 * width, | ||||
| 		Rect:   image.Rect(0, 0, width, height), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Clone returns a copy of the given image. | ||||
| func Clone(img image.Image) *image.NRGBA { | ||||
| 	src := newScanner(img) | ||||
| 	dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h)) | ||||
| 	size := src.w * 4 | ||||
| 	parallel(0, src.h, func(ys <-chan int) { | ||||
| 		for y := range ys { | ||||
| 			i := y * dst.Stride | ||||
| 			src.scan(0, y, src.w, y+1, dst.Pix[i:i+size]) | ||||
| 		} | ||||
| 	}) | ||||
| 	return dst | ||||
| } | ||||
|  | ||||
| // Anchor is the anchor point for image alignment. | ||||
| type Anchor int | ||||
|  | ||||
|   | ||||
							
								
								
									
										33
									
								
								vendor/github.com/lucasb-eyer/go-colorful/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/lucasb-eyer/go-colorful/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -124,17 +124,16 @@ Because a `colorful.Color` implements Go's `color.Color` interface (found in the | ||||
| `image/color` package), it can be used anywhere that expects a `color.Color`. | ||||
|  | ||||
| Furthermore, you can convert anything that implements the `color.Color` interface | ||||
| into a `colorful.Color` using the `MakeColorful` function: | ||||
| into a `colorful.Color` using the `MakeColor` function: | ||||
|  | ||||
| ```go | ||||
| c := colorful.MakeColor(color.Gray16{12345}) | ||||
| c, ok := colorful.MakeColor(color.Gray16{12345}) | ||||
| ``` | ||||
|  | ||||
| **Caveat:** Be aware that for this latter conversion  (using `MakeColor`) hits a corner-case | ||||
| when alpha is exactly zero. Because `color.Color` uses pre-multiplied alpha colors, | ||||
| this means the RGB values are lost and it's impossible to recover them. The current | ||||
| implementation `panic()`s in that case, see [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21) | ||||
| for discussion and suggesting alternatives. | ||||
| **Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a | ||||
| corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied | ||||
| alpha colors, this means the RGB values are lost (set to 0) and it's impossible | ||||
| to recover them. In such a case `MakeColor` will return `false` as its second value. | ||||
|  | ||||
| ### Comparing colors | ||||
| In the RGB color space, the Euclidian distance between colors *doesn't* correspond | ||||
| @@ -456,16 +455,26 @@ but that is outside the scope of this library. | ||||
| Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation, | ||||
| see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details. | ||||
|  | ||||
| ### Q: `MakeColor` panics when alpha is zero! | ||||
| A: Because in that case, the conversion is undefined. See | ||||
| [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21) | ||||
| as well as the short caveat discussion in the ["The `color.Color` interface"](README.md#the-colorcolor-interface) section above. | ||||
| ### Q: Why would `MakeColor` ever fail!? | ||||
| A: `MakeColor` fails when the alpha channel is zero. In that case, the | ||||
| conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21) | ||||
| as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface) | ||||
| section above. | ||||
|  | ||||
| Who? | ||||
| ==== | ||||
|  | ||||
| This library has been developed by Lucas Beyer with contributions from | ||||
| Bastien Dejean (@baskerville) and Phil Kulak (@pkulak). | ||||
| Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli). | ||||
|  | ||||
| Release Notes | ||||
| ============= | ||||
|  | ||||
| ### Version 1.0 | ||||
| - API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](https://github.com/lucasb-eyer/go-colorful#the-colorcolor-interface) section and [this FAQ entry](https://github.com/lucasb-eyer/go-colorful#q-why-would-makecolor-ever-fail) for details. | ||||
|  | ||||
| ### Version 0.9 | ||||
| - Initial version number after having ignored versioning for a long time :) | ||||
|  | ||||
| License: MIT | ||||
| ============ | ||||
|   | ||||
							
								
								
									
										7
									
								
								vendor/github.com/lucasb-eyer/go-colorful/colors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/lucasb-eyer/go-colorful/colors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -22,8 +22,11 @@ func (col Color) RGBA() (r, g, b, a uint32) { | ||||
| } | ||||
|  | ||||
| // Constructs a colorful.Color from something implementing color.Color | ||||
| func MakeColor(col color.Color) Color { | ||||
| func MakeColor(col color.Color) (Color, bool) { | ||||
| 	r, g, b, a := col.RGBA() | ||||
| 	if a == 0 { | ||||
| 		return Color{0, 0, 0}, false | ||||
| 	} | ||||
|  | ||||
| 	// Since color.Color is alpha pre-multiplied, we need to divide the | ||||
| 	// RGB values by alpha again in order to get back the original RGB. | ||||
| @@ -34,7 +37,7 @@ func MakeColor(col color.Color) Color { | ||||
| 	b *= 0xffff | ||||
| 	b /= a | ||||
|  | ||||
| 	return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0} | ||||
| 	return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true | ||||
| } | ||||
|  | ||||
| // Might come in handy sometimes to reduce boilerplate code. | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/github.com/mattn/go-runewidth/runewidth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/mattn/go-runewidth/runewidth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,13 +1,24 @@ | ||||
| package runewidth | ||||
|  | ||||
| import "os" | ||||
|  | ||||
| var ( | ||||
| 	// EastAsianWidth will be set true if the current locale is CJK | ||||
| 	EastAsianWidth = IsEastAsian() | ||||
| 	EastAsianWidth bool | ||||
|  | ||||
| 	// DefaultCondition is a condition in current locale | ||||
| 	DefaultCondition = &Condition{EastAsianWidth} | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	env := os.Getenv("RUNEWIDTH_EASTASIAN") | ||||
| 	if env == "" { | ||||
| 		EastAsianWidth = IsEastAsian() | ||||
| 	} else { | ||||
| 		EastAsianWidth = env == "1" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type interval struct { | ||||
| 	first rune | ||||
| 	last  rune | ||||
| @@ -55,6 +66,7 @@ var private = table{ | ||||
| var nonprint = table{ | ||||
| 	{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, | ||||
| 	{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, | ||||
| 	{0x2028, 0x2029}, | ||||
| 	{0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, | ||||
| 	{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/renstrom/fuzzysearch/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/renstrom/fuzzysearch/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2015 Peter Renström | ||||
| Copyright (c) 2018 Peter Lithammer | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
|   | ||||
							
								
								
									
										5
									
								
								vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -112,10 +112,7 @@ Outer: | ||||
| 	} | ||||
|  | ||||
| 	// Count up remaining char | ||||
| 	for len(target) > 0 { | ||||
| 		target = target[utf8.RuneLen(rune(target[0])):] | ||||
| 		runeDiff++ | ||||
| 	} | ||||
| 	runeDiff += utf8.RuneCountInString(target) | ||||
|  | ||||
| 	return runeDiff | ||||
| } | ||||
|   | ||||
							
								
								
									
										139
									
								
								vendor/github.com/stretchr/testify/assert/assertion_format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										139
									
								
								vendor/github.com/stretchr/testify/assert/assertion_format.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,6 +13,9 @@ import ( | ||||
|  | ||||
| // Conditionf uses a Comparison to assert a complex condition. | ||||
| func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Condition(t, comp, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -23,11 +26,17 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo | ||||
| //    assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") | ||||
| //    assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") | ||||
| func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Contains(t, s, contains, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. | ||||
| func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return DirExists(t, path, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -37,6 +46,9 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { | ||||
| // | ||||
| // assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") | ||||
| func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -45,6 +57,9 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string | ||||
| // | ||||
| //  assert.Emptyf(t, obj, "error message %s", "formatted") | ||||
| func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Empty(t, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -56,6 +71,9 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo | ||||
| // referenced values (as opposed to the memory addresses). Function equality | ||||
| // cannot be determined and will always fail. | ||||
| func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -65,6 +83,9 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar | ||||
| //   actualObj, err := SomeFunction() | ||||
| //   assert.EqualErrorf(t, err,  expectedErrorString, "error message %s", "formatted") | ||||
| func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -73,6 +94,9 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args | ||||
| // | ||||
| //    assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123)) | ||||
| func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -83,6 +107,9 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri | ||||
| // 	   assert.Equal(t, expectedErrorf, err) | ||||
| //   } | ||||
| func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Error(t, err, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -90,16 +117,25 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { | ||||
| // | ||||
| //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123)) | ||||
| func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // Failf reports a failure through | ||||
| func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Fail(t, failureMessage, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // FailNowf fails test | ||||
| func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -107,31 +143,43 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} | ||||
| // | ||||
| //    assert.Falsef(t, myBool, "error message %s", "formatted") | ||||
| func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return False(t, value, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. | ||||
| func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FileExists(t, path, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyContainsf asserts that a specified handler returns a | ||||
| // body that contains a string. | ||||
| // | ||||
| //  assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| //  assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyNotContainsf asserts that a specified handler returns a | ||||
| // body that does not contain a string. | ||||
| // | ||||
| //  assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| //  assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -141,6 +189,9 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u | ||||
| // | ||||
| // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). | ||||
| func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -150,6 +201,9 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, | ||||
| // | ||||
| // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). | ||||
| func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -159,6 +213,9 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -166,6 +223,9 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin | ||||
| // | ||||
| //    assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) | ||||
| func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -173,31 +233,49 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms | ||||
| // | ||||
| // 	 assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) | ||||
| func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. | ||||
| func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // InDeltaSlicef is the same as InDelta, except it compares two slices. | ||||
| func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // InEpsilonf asserts that expected and actual have a relative error less than epsilon | ||||
| func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. | ||||
| func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // IsTypef asserts that the specified objects are of the same type. | ||||
| func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -205,6 +283,9 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin | ||||
| // | ||||
| //  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") | ||||
| func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -213,6 +294,9 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int | ||||
| // | ||||
| //    assert.Lenf(t, mySlice, 3, "error message %s", "formatted") | ||||
| func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Len(t, object, length, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -220,6 +304,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf | ||||
| // | ||||
| //    assert.Nilf(t, err, "error message %s", "formatted") | ||||
| func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Nil(t, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -230,6 +317,9 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool | ||||
| // 	   assert.Equal(t, expectedObj, actualObj) | ||||
| //   } | ||||
| func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NoError(t, err, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -240,6 +330,9 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { | ||||
| //    assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") | ||||
| //    assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") | ||||
| func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -250,6 +343,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a | ||||
| //    assert.Equal(t, "two", obj[1]) | ||||
| //  } | ||||
| func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEmpty(t, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -260,6 +356,9 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) | ||||
| // Pointer variable equality is determined based on the equality of the | ||||
| // referenced values (as opposed to the memory addresses). | ||||
| func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -267,6 +366,9 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, | ||||
| // | ||||
| //    assert.NotNilf(t, err, "error message %s", "formatted") | ||||
| func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotNil(t, object, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -274,6 +376,9 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo | ||||
| // | ||||
| //   assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") | ||||
| func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotPanics(t, f, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -282,6 +387,9 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo | ||||
| //  assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") | ||||
| //  assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") | ||||
| func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -290,11 +398,17 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. | ||||
| // | ||||
| //    assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") | ||||
| func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // NotZerof asserts that i is not the zero value for its type. | ||||
| func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotZero(t, i, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -302,6 +416,9 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { | ||||
| // | ||||
| //   assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") | ||||
| func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Panics(t, f, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -310,6 +427,9 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool | ||||
| // | ||||
| //   assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") | ||||
| func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -318,6 +438,9 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str | ||||
| //  assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") | ||||
| //  assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") | ||||
| func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Regexp(t, rx, str, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -326,6 +449,9 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in | ||||
| // | ||||
| //    assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") | ||||
| func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Subset(t, list, subset, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -333,6 +459,9 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args | ||||
| // | ||||
| //    assert.Truef(t, myBool, "error message %s", "formatted") | ||||
| func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return True(t, value, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| @@ -340,10 +469,16 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { | ||||
| // | ||||
| //   assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") | ||||
| func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|  | ||||
| // Zerof asserts that i is the zero value for its type. | ||||
| func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Zero(t, i, append([]interface{}{msg}, args...)...) | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| {{.CommentFormat}} | ||||
| func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { h.Helper() } | ||||
| 	return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										278
									
								
								vendor/github.com/stretchr/testify/assert/assertion_forward.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										278
									
								
								vendor/github.com/stretchr/testify/assert/assertion_forward.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,11 +13,17 @@ import ( | ||||
|  | ||||
| // Condition uses a Comparison to assert a complex condition. | ||||
| func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Condition(a.t, comp, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // Conditionf uses a Comparison to assert a complex condition. | ||||
| func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Conditionf(a.t, comp, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -28,6 +34,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{} | ||||
| //    a.Contains(["Hello", "World"], "World") | ||||
| //    a.Contains({"Hello": "World"}, "Hello") | ||||
| func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Contains(a.t, s, contains, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -38,16 +47,25 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs .. | ||||
| //    a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") | ||||
| //    a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") | ||||
| func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Containsf(a.t, s, contains, msg, args...) | ||||
| } | ||||
|  | ||||
| // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. | ||||
| func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return DirExists(a.t, path, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. | ||||
| func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return DirExistsf(a.t, path, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -57,6 +75,9 @@ func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bo | ||||
| // | ||||
| // a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) | ||||
| func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return ElementsMatch(a.t, listA, listB, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -66,6 +87,9 @@ func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndA | ||||
| // | ||||
| // a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") | ||||
| func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return ElementsMatchf(a.t, listA, listB, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -74,6 +98,9 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st | ||||
| // | ||||
| //  a.Empty(obj) | ||||
| func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Empty(a.t, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -82,6 +109,9 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //  a.Emptyf(obj, "error message %s", "formatted") | ||||
| func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Emptyf(a.t, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -93,6 +123,9 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) | ||||
| // referenced values (as opposed to the memory addresses). Function equality | ||||
| // cannot be determined and will always fail. | ||||
| func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Equal(a.t, expected, actual, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -102,6 +135,9 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs | ||||
| //   actualObj, err := SomeFunction() | ||||
| //   a.EqualError(err,  expectedErrorString) | ||||
| func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualError(a.t, theError, errString, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -111,6 +147,9 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... | ||||
| //   actualObj, err := SomeFunction() | ||||
| //   a.EqualErrorf(err,  expectedErrorString, "error message %s", "formatted") | ||||
| func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualErrorf(a.t, theError, errString, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -119,6 +158,9 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a | ||||
| // | ||||
| //    a.EqualValues(uint32(123), int32(123)) | ||||
| func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualValues(a.t, expected, actual, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -127,6 +169,9 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn | ||||
| // | ||||
| //    a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123)) | ||||
| func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return EqualValuesf(a.t, expected, actual, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -138,6 +183,9 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg | ||||
| // referenced values (as opposed to the memory addresses). Function equality | ||||
| // cannot be determined and will always fail. | ||||
| func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Equalf(a.t, expected, actual, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -148,6 +196,9 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string | ||||
| // 	   assert.Equal(t, expectedError, err) | ||||
| //   } | ||||
| func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Error(a.t, err, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -158,6 +209,9 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { | ||||
| // 	   assert.Equal(t, expectedErrorf, err) | ||||
| //   } | ||||
| func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Errorf(a.t, err, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -165,6 +219,9 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { | ||||
| // | ||||
| //    a.Exactly(int32(123), int64(123)) | ||||
| func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Exactly(a.t, expected, actual, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -172,26 +229,41 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg | ||||
| // | ||||
| //    a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123)) | ||||
| func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Exactlyf(a.t, expected, actual, msg, args...) | ||||
| } | ||||
|  | ||||
| // Fail reports a failure through | ||||
| func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Fail(a.t, failureMessage, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // FailNow fails test | ||||
| func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FailNow(a.t, failureMessage, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // FailNowf fails test | ||||
| func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FailNowf(a.t, failureMessage, msg, args...) | ||||
| } | ||||
|  | ||||
| // Failf reports a failure through | ||||
| func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Failf(a.t, failureMessage, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -199,6 +271,9 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{ | ||||
| // | ||||
| //    a.False(myBool) | ||||
| func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return False(a.t, value, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -206,56 +281,77 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //    a.Falsef(myBool, "error message %s", "formatted") | ||||
| func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Falsef(a.t, value, msg, args...) | ||||
| } | ||||
|  | ||||
| // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. | ||||
| func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FileExists(a.t, path, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. | ||||
| func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return FileExistsf(a.t, path, msg, args...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyContains asserts that a specified handler returns a | ||||
| // body that contains a string. | ||||
| // | ||||
| //  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") | ||||
| //  a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyContainsf asserts that a specified handler returns a | ||||
| // body that contains a string. | ||||
| // | ||||
| //  a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| //  a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyNotContains asserts that a specified handler returns a | ||||
| // body that does not contain a string. | ||||
| // | ||||
| //  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") | ||||
| //  a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // HTTPBodyNotContainsf asserts that a specified handler returns a | ||||
| // body that does not contain a string. | ||||
| // | ||||
| //  a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| //  a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -265,6 +361,9 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPError(a.t, handler, method, url, values, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -274,6 +373,9 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri | ||||
| // | ||||
| // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). | ||||
| func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPErrorf(a.t, handler, method, url, values, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -283,6 +385,9 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -292,6 +397,9 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s | ||||
| // | ||||
| // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). | ||||
| func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPRedirectf(a.t, handler, method, url, values, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -301,6 +409,9 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -310,6 +421,9 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return HTTPSuccessf(a.t, handler, method, url, values, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -317,6 +431,9 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s | ||||
| // | ||||
| //    a.Implements((*MyInterface)(nil), new(MyObject)) | ||||
| func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Implements(a.t, interfaceObject, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -324,6 +441,9 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, | ||||
| // | ||||
| //    a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) | ||||
| func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Implementsf(a.t, interfaceObject, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -331,26 +451,41 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{} | ||||
| // | ||||
| // 	 a.InDelta(math.Pi, (22 / 7.0), 0.01) | ||||
| func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDelta(a.t, expected, actual, delta, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. | ||||
| func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. | ||||
| func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) | ||||
| } | ||||
|  | ||||
| // InDeltaSlice is the same as InDelta, except it compares two slices. | ||||
| func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // InDeltaSlicef is the same as InDelta, except it compares two slices. | ||||
| func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaSlicef(a.t, expected, actual, delta, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -358,36 +493,57 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del | ||||
| // | ||||
| // 	 a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) | ||||
| func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InDeltaf(a.t, expected, actual, delta, msg, args...) | ||||
| } | ||||
|  | ||||
| // InEpsilon asserts that expected and actual have a relative error less than epsilon | ||||
| func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. | ||||
| func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. | ||||
| func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) | ||||
| } | ||||
|  | ||||
| // InEpsilonf asserts that expected and actual have a relative error less than epsilon | ||||
| func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return InEpsilonf(a.t, expected, actual, epsilon, msg, args...) | ||||
| } | ||||
|  | ||||
| // IsType asserts that the specified objects are of the same type. | ||||
| func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return IsType(a.t, expectedType, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // IsTypef asserts that the specified objects are of the same type. | ||||
| func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return IsTypef(a.t, expectedType, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -395,6 +551,9 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s | ||||
| // | ||||
| //  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) | ||||
| func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return JSONEq(a.t, expected, actual, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -402,6 +561,9 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf | ||||
| // | ||||
| //  a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") | ||||
| func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return JSONEqf(a.t, expected, actual, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -410,6 +572,9 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. | ||||
| // | ||||
| //    a.Len(mySlice, 3) | ||||
| func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Len(a.t, object, length, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -418,6 +583,9 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface | ||||
| // | ||||
| //    a.Lenf(mySlice, 3, "error message %s", "formatted") | ||||
| func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Lenf(a.t, object, length, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -425,6 +593,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in | ||||
| // | ||||
| //    a.Nil(err) | ||||
| func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Nil(a.t, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -432,6 +603,9 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //    a.Nilf(err, "error message %s", "formatted") | ||||
| func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Nilf(a.t, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -442,6 +616,9 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b | ||||
| // 	   assert.Equal(t, expectedObj, actualObj) | ||||
| //   } | ||||
| func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NoError(a.t, err, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -452,6 +629,9 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { | ||||
| // 	   assert.Equal(t, expectedObj, actualObj) | ||||
| //   } | ||||
| func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NoErrorf(a.t, err, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -462,6 +642,9 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { | ||||
| //    a.NotContains(["Hello", "World"], "Earth") | ||||
| //    a.NotContains({"Hello": "World"}, "Earth") | ||||
| func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotContains(a.t, s, contains, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -472,6 +655,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs | ||||
| //    a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") | ||||
| //    a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") | ||||
| func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotContainsf(a.t, s, contains, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -482,6 +668,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin | ||||
| //    assert.Equal(t, "two", obj[1]) | ||||
| //  } | ||||
| func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEmpty(a.t, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -492,6 +681,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo | ||||
| //    assert.Equal(t, "two", obj[1]) | ||||
| //  } | ||||
| func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEmptyf(a.t, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -502,6 +694,9 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface | ||||
| // Pointer variable equality is determined based on the equality of the | ||||
| // referenced values (as opposed to the memory addresses). | ||||
| func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEqual(a.t, expected, actual, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -512,6 +707,9 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr | ||||
| // Pointer variable equality is determined based on the equality of the | ||||
| // referenced values (as opposed to the memory addresses). | ||||
| func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotEqualf(a.t, expected, actual, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -519,6 +717,9 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str | ||||
| // | ||||
| //    a.NotNil(err) | ||||
| func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotNil(a.t, object, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -526,6 +727,9 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool | ||||
| // | ||||
| //    a.NotNilf(err, "error message %s", "formatted") | ||||
| func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotNilf(a.t, object, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -533,6 +737,9 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{} | ||||
| // | ||||
| //   a.NotPanics(func(){ RemainCalm() }) | ||||
| func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotPanics(a.t, f, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -540,6 +747,9 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool | ||||
| // | ||||
| //   a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") | ||||
| func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotPanicsf(a.t, f, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -548,6 +758,9 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{} | ||||
| //  a.NotRegexp(regexp.MustCompile("starts"), "it's starting") | ||||
| //  a.NotRegexp("^start", "it's not starting") | ||||
| func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotRegexp(a.t, rx, str, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -556,6 +769,9 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in | ||||
| //  a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") | ||||
| //  a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") | ||||
| func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotRegexpf(a.t, rx, str, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -564,6 +780,9 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg | ||||
| // | ||||
| //    a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") | ||||
| func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotSubset(a.t, list, subset, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -572,16 +791,25 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs | ||||
| // | ||||
| //    a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") | ||||
| func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotSubsetf(a.t, list, subset, msg, args...) | ||||
| } | ||||
|  | ||||
| // NotZero asserts that i is not the zero value for its type. | ||||
| func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotZero(a.t, i, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // NotZerof asserts that i is not the zero value for its type. | ||||
| func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return NotZerof(a.t, i, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -589,6 +817,9 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo | ||||
| // | ||||
| //   a.Panics(func(){ GoCrazy() }) | ||||
| func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Panics(a.t, f, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -597,6 +828,9 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //   a.PanicsWithValue("crazy error", func(){ GoCrazy() }) | ||||
| func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return PanicsWithValue(a.t, expected, f, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -605,6 +839,9 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA | ||||
| // | ||||
| //   a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") | ||||
| func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return PanicsWithValuef(a.t, expected, f, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -612,6 +849,9 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg | ||||
| // | ||||
| //   a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") | ||||
| func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Panicsf(a.t, f, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -620,6 +860,9 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b | ||||
| //  a.Regexp(regexp.MustCompile("start"), "it's starting") | ||||
| //  a.Regexp("start...$", "it's not starting") | ||||
| func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Regexp(a.t, rx, str, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -628,6 +871,9 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter | ||||
| //  a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") | ||||
| //  a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") | ||||
| func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Regexpf(a.t, rx, str, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -636,6 +882,9 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args . | ||||
| // | ||||
| //    a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") | ||||
| func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Subset(a.t, list, subset, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -644,6 +893,9 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ... | ||||
| // | ||||
| //    a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") | ||||
| func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Subsetf(a.t, list, subset, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -651,6 +903,9 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a | ||||
| // | ||||
| //    a.True(myBool) | ||||
| func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return True(a.t, value, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -658,6 +913,9 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //    a.Truef(myBool, "error message %s", "formatted") | ||||
| func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Truef(a.t, value, msg, args...) | ||||
| } | ||||
|  | ||||
| @@ -665,6 +923,9 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { | ||||
| // | ||||
| //   a.WithinDuration(time.Now(), time.Now(), 10*time.Second) | ||||
| func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| @@ -672,15 +933,24 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta | ||||
| // | ||||
| //   a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") | ||||
| func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return WithinDurationf(a.t, expected, actual, delta, msg, args...) | ||||
| } | ||||
|  | ||||
| // Zero asserts that i is the zero value for its type. | ||||
| func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Zero(a.t, i, msgAndArgs...) | ||||
| } | ||||
|  | ||||
| // Zerof asserts that i is the zero value for its type. | ||||
| func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	return Zerof(a.t, i, msg, args...) | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| {{.CommentWithoutT "a"}} | ||||
| func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { | ||||
| 	if h, ok := a.t.(tHelper); ok { h.Helper() } | ||||
| 	return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										206
									
								
								vendor/github.com/stretchr/testify/assert/assertions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										206
									
								
								vendor/github.com/stretchr/testify/assert/assertions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -27,6 +27,22 @@ type TestingT interface { | ||||
| 	Errorf(format string, args ...interface{}) | ||||
| } | ||||
|  | ||||
| // ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful | ||||
| // for table driven tests. | ||||
| type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool | ||||
|  | ||||
| // ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful | ||||
| // for table driven tests. | ||||
| type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool | ||||
|  | ||||
| // BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful | ||||
| // for table driven tests. | ||||
| type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool | ||||
|  | ||||
| // ValuesAssertionFunc is a common function prototype when validating an error value.  Can be useful | ||||
| // for table driven tests. | ||||
| type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool | ||||
|  | ||||
| // Comparison a custom function that returns true on success and false on failure | ||||
| type Comparison func() (success bool) | ||||
|  | ||||
| @@ -38,22 +54,24 @@ type Comparison func() (success bool) | ||||
| // | ||||
| // This function does no assertion of any kind. | ||||
| func ObjectsAreEqual(expected, actual interface{}) bool { | ||||
|  | ||||
| 	if expected == nil || actual == nil { | ||||
| 		return expected == actual | ||||
| 	} | ||||
| 	if exp, ok := expected.([]byte); ok { | ||||
|  | ||||
| 	exp, ok := expected.([]byte) | ||||
| 	if !ok { | ||||
| 		return reflect.DeepEqual(expected, actual) | ||||
| 	} | ||||
|  | ||||
| 	act, ok := actual.([]byte) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 		} else if exp == nil || act == nil { | ||||
| 	} | ||||
| 	if exp == nil || act == nil { | ||||
| 		return exp == nil && act == nil | ||||
| 	} | ||||
| 	return bytes.Equal(exp, act) | ||||
| } | ||||
| 	return reflect.DeepEqual(expected, actual) | ||||
|  | ||||
| } | ||||
|  | ||||
| // ObjectsAreEqualValues gets whether two objects are equal, or if their | ||||
| // values are equal. | ||||
| @@ -156,21 +174,6 @@ func isTest(name, prefix string) bool { | ||||
| 	return !unicode.IsLower(rune) | ||||
| } | ||||
|  | ||||
| // getWhitespaceString returns a string that is long enough to overwrite the default | ||||
| // output from the go testing framework. | ||||
| func getWhitespaceString() string { | ||||
|  | ||||
| 	_, file, line, ok := runtime.Caller(1) | ||||
| 	if !ok { | ||||
| 		return "" | ||||
| 	} | ||||
| 	parts := strings.Split(file, "/") | ||||
| 	file = parts[len(parts)-1] | ||||
|  | ||||
| 	return strings.Repeat(" ", len(fmt.Sprintf("%s:%d:        ", file, line))) | ||||
|  | ||||
| } | ||||
|  | ||||
| func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { | ||||
| 	if len(msgAndArgs) == 0 || msgAndArgs == nil { | ||||
| 		return "" | ||||
| @@ -195,7 +198,7 @@ func indentMessageLines(message string, longestLabelLen int) string { | ||||
| 		// no need to align first line because it starts at the correct location (after the label) | ||||
| 		if i != 0 { | ||||
| 			// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab | ||||
| 			outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") | ||||
| 			outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") | ||||
| 		} | ||||
| 		outBuf.WriteString(scanner.Text()) | ||||
| 	} | ||||
| @@ -209,6 +212,9 @@ type failNower interface { | ||||
|  | ||||
| // FailNow fails test | ||||
| func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	Fail(t, failureMessage, msgAndArgs...) | ||||
|  | ||||
| 	// We cannot extend TestingT with FailNow() and | ||||
| @@ -227,8 +233,11 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool | ||||
|  | ||||
| // Fail reports a failure through | ||||
| func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	content := []labeledContent{ | ||||
| 		{"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")}, | ||||
| 		{"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, | ||||
| 		{"Error", failureMessage}, | ||||
| 	} | ||||
|  | ||||
| @@ -244,7 +253,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { | ||||
| 		content = append(content, labeledContent{"Messages", message}) | ||||
| 	} | ||||
|  | ||||
| 	t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...)) | ||||
| 	t.Errorf("\n%s", ""+labeledOutput(content...)) | ||||
|  | ||||
| 	return false | ||||
| } | ||||
| @@ -256,7 +265,7 @@ type labeledContent struct { | ||||
|  | ||||
| // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: | ||||
| // | ||||
| //   \r\t{{label}}:{{align_spaces}}\t{{content}}\n | ||||
| //   \t{{label}}:{{align_spaces}}\t{{content}}\n | ||||
| // | ||||
| // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. | ||||
| // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this | ||||
| @@ -272,7 +281,7 @@ func labeledOutput(content ...labeledContent) string { | ||||
| 	} | ||||
| 	var output string | ||||
| 	for _, v := range content { | ||||
| 		output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" | ||||
| 		output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" | ||||
| 	} | ||||
| 	return output | ||||
| } | ||||
| @@ -281,6 +290,9 @@ func labeledOutput(content ...labeledContent) string { | ||||
| // | ||||
| //    assert.Implements(t, (*MyInterface)(nil), new(MyObject)) | ||||
| func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	interfaceType := reflect.TypeOf(interfaceObject).Elem() | ||||
|  | ||||
| 	if object == nil { | ||||
| @@ -295,6 +307,9 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg | ||||
|  | ||||
| // IsType asserts that the specified objects are of the same type. | ||||
| func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { | ||||
| 		return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) | ||||
| @@ -311,6 +326,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs | ||||
| // referenced values (as opposed to the memory addresses). Function equality | ||||
| // cannot be determined and will always fail. | ||||
| func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if err := validateEqualArgs(expected, actual); err != nil { | ||||
| 		return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", | ||||
| 			expected, actual, err), msgAndArgs...) | ||||
| @@ -349,6 +367,9 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) { | ||||
| // | ||||
| //    assert.EqualValues(t, uint32(123), int32(123)) | ||||
| func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if !ObjectsAreEqualValues(expected, actual) { | ||||
| 		diff := diff(expected, actual) | ||||
| @@ -366,12 +387,15 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa | ||||
| // | ||||
| //    assert.Exactly(t, int32(123), int64(123)) | ||||
| func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	aType := reflect.TypeOf(expected) | ||||
| 	bType := reflect.TypeOf(actual) | ||||
|  | ||||
| 	if aType != bType { | ||||
| 		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...) | ||||
| 		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) | ||||
| 	} | ||||
|  | ||||
| 	return Equal(t, expected, actual, msgAndArgs...) | ||||
| @@ -382,6 +406,9 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} | ||||
| // | ||||
| //    assert.NotNil(t, err) | ||||
| func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if !isNil(object) { | ||||
| 		return true | ||||
| 	} | ||||
| @@ -407,6 +434,9 @@ func isNil(object interface{}) bool { | ||||
| // | ||||
| //    assert.Nil(t, err) | ||||
| func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if isNil(object) { | ||||
| 		return true | ||||
| 	} | ||||
| @@ -446,6 +476,9 @@ func isEmpty(object interface{}) bool { | ||||
| // | ||||
| //  assert.Empty(t, obj) | ||||
| func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	pass := isEmpty(object) | ||||
| 	if !pass { | ||||
| @@ -463,6 +496,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| //    assert.Equal(t, "two", obj[1]) | ||||
| //  } | ||||
| func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	pass := !isEmpty(object) | ||||
| 	if !pass { | ||||
| @@ -490,6 +526,9 @@ func getLen(x interface{}) (ok bool, length int) { | ||||
| // | ||||
| //    assert.Len(t, mySlice, 3) | ||||
| func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	ok, l := getLen(object) | ||||
| 	if !ok { | ||||
| 		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) | ||||
| @@ -505,6 +544,14 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) | ||||
| // | ||||
| //    assert.True(t, myBool) | ||||
| func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if h, ok := t.(interface { | ||||
| 		Helper() | ||||
| 	}); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if value != true { | ||||
| 		return Fail(t, "Should be true", msgAndArgs...) | ||||
| @@ -518,6 +565,9 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //    assert.False(t, myBool) | ||||
| func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if value != false { | ||||
| 		return Fail(t, "Should be false", msgAndArgs...) | ||||
| @@ -534,6 +584,9 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { | ||||
| // Pointer variable equality is determined based on the equality of the | ||||
| // referenced values (as opposed to the memory addresses). | ||||
| func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if err := validateEqualArgs(expected, actual); err != nil { | ||||
| 		return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", | ||||
| 			expected, actual, err), msgAndArgs...) | ||||
| @@ -592,6 +645,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) { | ||||
| //    assert.Contains(t, ["Hello", "World"], "World") | ||||
| //    assert.Contains(t, {"Hello": "World"}, "Hello") | ||||
| func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	ok, found := includeElement(s, contains) | ||||
| 	if !ok { | ||||
| @@ -612,6 +668,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo | ||||
| //    assert.NotContains(t, ["Hello", "World"], "Earth") | ||||
| //    assert.NotContains(t, {"Hello": "World"}, "Earth") | ||||
| func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	ok, found := includeElement(s, contains) | ||||
| 	if !ok { | ||||
| @@ -630,6 +689,9 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) | ||||
| // | ||||
| //    assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") | ||||
| func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if subset == nil { | ||||
| 		return true // we consider nil to be equal to the nil set | ||||
| 	} | ||||
| @@ -671,6 +733,9 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok | ||||
| // | ||||
| //    assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") | ||||
| func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if subset == nil { | ||||
| 		return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) | ||||
| 	} | ||||
| @@ -713,6 +778,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) | ||||
| // | ||||
| // assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) | ||||
| func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if isEmpty(listA) && isEmpty(listB) { | ||||
| 		return true | ||||
| 	} | ||||
| @@ -763,6 +831,9 @@ func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface | ||||
|  | ||||
| // Condition uses a Comparison to assert a complex condition. | ||||
| func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	result := comp() | ||||
| 	if !result { | ||||
| 		Fail(t, "Condition failed!", msgAndArgs...) | ||||
| @@ -800,9 +871,12 @@ func didPanic(f PanicTestFunc) (bool, interface{}) { | ||||
| // | ||||
| //   assert.Panics(t, func(){ GoCrazy() }) | ||||
| func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| @@ -813,13 +887,16 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //   assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) | ||||
| func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	funcDidPanic, panicValue := didPanic(f) | ||||
| 	if !funcDidPanic { | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) | ||||
| 	} | ||||
| 	if panicValue != expected { | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...) | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...) | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| @@ -829,9 +906,12 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr | ||||
| // | ||||
| //   assert.NotPanics(t, func(){ RemainCalm() }) | ||||
| func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if funcDidPanic, panicValue := didPanic(f); funcDidPanic { | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) | ||||
| 		return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...) | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| @@ -841,6 +921,9 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) | ||||
| func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	dt := expected.Sub(actual) | ||||
| 	if dt < -delta || dt > delta { | ||||
| @@ -890,6 +973,9 @@ func toFloat(x interface{}) (float64, bool) { | ||||
| // | ||||
| // 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) | ||||
| func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	af, aok := toFloat(expected) | ||||
| 	bf, bok := toFloat(actual) | ||||
| @@ -916,6 +1002,9 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs | ||||
|  | ||||
| // InDeltaSlice is the same as InDelta, except it compares two slices. | ||||
| func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if expected == nil || actual == nil || | ||||
| 		reflect.TypeOf(actual).Kind() != reflect.Slice || | ||||
| 		reflect.TypeOf(expected).Kind() != reflect.Slice { | ||||
| @@ -937,6 +1026,9 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn | ||||
|  | ||||
| // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. | ||||
| func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if expected == nil || actual == nil || | ||||
| 		reflect.TypeOf(actual).Kind() != reflect.Map || | ||||
| 		reflect.TypeOf(expected).Kind() != reflect.Map { | ||||
| @@ -994,6 +1086,9 @@ func calcRelativeError(expected, actual interface{}) (float64, error) { | ||||
|  | ||||
| // InEpsilon asserts that expected and actual have a relative error less than epsilon | ||||
| func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	actualEpsilon, err := calcRelativeError(expected, actual) | ||||
| 	if err != nil { | ||||
| 		return Fail(t, err.Error(), msgAndArgs...) | ||||
| @@ -1008,6 +1103,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd | ||||
|  | ||||
| // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. | ||||
| func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if expected == nil || actual == nil || | ||||
| 		reflect.TypeOf(actual).Kind() != reflect.Slice || | ||||
| 		reflect.TypeOf(expected).Kind() != reflect.Slice { | ||||
| @@ -1038,6 +1136,9 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m | ||||
| //	   assert.Equal(t, expectedObj, actualObj) | ||||
| //   } | ||||
| func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) | ||||
| 	} | ||||
| @@ -1052,6 +1153,9 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { | ||||
| //	   assert.Equal(t, expectedError, err) | ||||
| //   } | ||||
| func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	if err == nil { | ||||
| 		return Fail(t, "An error is expected but got nil.", msgAndArgs...) | ||||
| @@ -1066,6 +1170,9 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { | ||||
| //   actualObj, err := SomeFunction() | ||||
| //   assert.EqualError(t, err,  expectedErrorString) | ||||
| func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if !Error(t, theError, msgAndArgs...) { | ||||
| 		return false | ||||
| 	} | ||||
| @@ -1099,6 +1206,9 @@ func matchRegexp(rx interface{}, str interface{}) bool { | ||||
| //  assert.Regexp(t, regexp.MustCompile("start"), "it's starting") | ||||
| //  assert.Regexp(t, "start...$", "it's not starting") | ||||
| func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
|  | ||||
| 	match := matchRegexp(rx, str) | ||||
|  | ||||
| @@ -1114,6 +1224,9 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface | ||||
| //  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") | ||||
| //  assert.NotRegexp(t, "^start", "it's not starting") | ||||
| func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	match := matchRegexp(rx, str) | ||||
|  | ||||
| 	if match { | ||||
| @@ -1126,6 +1239,9 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf | ||||
|  | ||||
| // Zero asserts that i is the zero value for its type. | ||||
| func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { | ||||
| 		return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) | ||||
| 	} | ||||
| @@ -1134,6 +1250,9 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { | ||||
|  | ||||
| // NotZero asserts that i is not the zero value for its type. | ||||
| func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { | ||||
| 		return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) | ||||
| 	} | ||||
| @@ -1142,6 +1261,9 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { | ||||
|  | ||||
| // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. | ||||
| func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	info, err := os.Lstat(path) | ||||
| 	if err != nil { | ||||
| 		if os.IsNotExist(err) { | ||||
| @@ -1157,6 +1279,9 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { | ||||
|  | ||||
| // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. | ||||
| func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	info, err := os.Lstat(path) | ||||
| 	if err != nil { | ||||
| 		if os.IsNotExist(err) { | ||||
| @@ -1174,6 +1299,9 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { | ||||
| // | ||||
| //  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) | ||||
| func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	var expectedJSONAsInterface, actualJSONAsInterface interface{} | ||||
|  | ||||
| 	if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { | ||||
| @@ -1212,12 +1340,18 @@ func diff(expected interface{}, actual interface{}) string { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array { | ||||
| 	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	e := spewConfig.Sdump(expected) | ||||
| 	a := spewConfig.Sdump(actual) | ||||
| 	var e, a string | ||||
| 	if ek != reflect.String { | ||||
| 		e = spewConfig.Sdump(expected) | ||||
| 		a = spewConfig.Sdump(actual) | ||||
| 	} else { | ||||
| 		e = expected.(string) | ||||
| 		a = actual.(string) | ||||
| 	} | ||||
|  | ||||
| 	diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ | ||||
| 		A:        difflib.SplitLines(e), | ||||
| @@ -1254,3 +1388,7 @@ var spewConfig = spew.ConfigState{ | ||||
| 	DisableCapacities:       true, | ||||
| 	SortKeys:                true, | ||||
| } | ||||
|  | ||||
| type tHelper interface { | ||||
| 	Helper() | ||||
| } | ||||
|   | ||||
							
								
								
									
										22
									
								
								vendor/github.com/stretchr/testify/assert/http_assertions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/stretchr/testify/assert/http_assertions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -12,10 +12,11 @@ import ( | ||||
| // an error if building a new request fails. | ||||
| func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { | ||||
| 	w := httptest.NewRecorder() | ||||
| 	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) | ||||
| 	req, err := http.NewRequest(method, url, nil) | ||||
| 	if err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
| 	req.URL.RawQuery = values.Encode() | ||||
| 	handler(w, req) | ||||
| 	return w.Code, nil | ||||
| } | ||||
| @@ -26,6 +27,9 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) ( | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	code, err := httpCode(handler, method, url, values) | ||||
| 	if err != nil { | ||||
| 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) | ||||
| @@ -46,6 +50,9 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	code, err := httpCode(handler, method, url, values) | ||||
| 	if err != nil { | ||||
| 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) | ||||
| @@ -66,6 +73,9 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	code, err := httpCode(handler, method, url, values) | ||||
| 	if err != nil { | ||||
| 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) | ||||
| @@ -95,10 +105,13 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s | ||||
| // HTTPBodyContains asserts that a specified handler returns a | ||||
| // body that contains a string. | ||||
| // | ||||
| //  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") | ||||
| //  assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	body := HTTPBody(handler, method, url, values) | ||||
|  | ||||
| 	contains := strings.Contains(body, fmt.Sprint(str)) | ||||
| @@ -112,10 +125,13 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, | ||||
| // HTTPBodyNotContains asserts that a specified handler returns a | ||||
| // body that does not contain a string. | ||||
| // | ||||
| //  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") | ||||
| //  assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") | ||||
| // | ||||
| // Returns whether the assertion was successful (true) or not (false). | ||||
| func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { | ||||
| 	if h, ok := t.(tHelper); ok { | ||||
| 		h.Helper() | ||||
| 	} | ||||
| 	body := HTTPBody(handler, method, url, values) | ||||
|  | ||||
| 	contains := strings.Contains(body, fmt.Sprint(str)) | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/zyedidia/clipboard/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/zyedidia/clipboard/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,7 @@ | ||||
| Copyright (c) 2018 Zachary Yedidia. Modifications to atotto/clipboard. | ||||
|  | ||||
| Original license: | ||||
|  | ||||
| Copyright (c) 2013 Ato Araki. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/zyedidia/clipboard/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/zyedidia/clipboard/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,7 @@ | ||||
| # This is a fork of atotto/clipboard | ||||
|  | ||||
| This fork is used for `zyedidia/micro` and has some modifications, namely: support for the primary clipboard on linux and support for an internal clipboard if the system clipboard is not available. | ||||
|  | ||||
| [](https://travis-ci.org/atotto/clipboard) [](https://drone.io/github.com/atotto/clipboard/latest)  | ||||
|  | ||||
| [](http://godoc.org/github.com/atotto/clipboard) | ||||
|   | ||||
							
								
								
									
										100
									
								
								vendor/golang.org/x/image/bmp/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										100
									
								
								vendor/golang.org/x/image/bmp/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -49,8 +49,9 @@ func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error { | ||||
| func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { | ||||
| 	buf := make([]byte, step) | ||||
| 	if opaque { | ||||
| 		for y := dy - 1; y >= 0; y-- { | ||||
| 			min := y*stride + 0 | ||||
| 			max := y*stride + dx*4 | ||||
| @@ -65,6 +66,76 @@ func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		for y := dy - 1; y >= 0; y-- { | ||||
| 			min := y*stride + 0 | ||||
| 			max := y*stride + dx*4 | ||||
| 			off := 0 | ||||
| 			for i := min; i < max; i += 4 { | ||||
| 				a := uint32(pix[i+3]) | ||||
| 				if a == 0 { | ||||
| 					buf[off+2] = 0 | ||||
| 					buf[off+1] = 0 | ||||
| 					buf[off+0] = 0 | ||||
| 					buf[off+3] = 0 | ||||
| 					off += 4 | ||||
| 					continue | ||||
| 				} else if a == 0xff { | ||||
| 					buf[off+2] = pix[i+0] | ||||
| 					buf[off+1] = pix[i+1] | ||||
| 					buf[off+0] = pix[i+2] | ||||
| 					buf[off+3] = 0xff | ||||
| 					off += 4 | ||||
| 					continue | ||||
| 				} | ||||
| 				buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8) | ||||
| 				buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8) | ||||
| 				buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8) | ||||
| 				buf[off+3] = uint8(a) | ||||
| 				off += 4 | ||||
| 			} | ||||
| 			if _, err := w.Write(buf); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { | ||||
| 	buf := make([]byte, step) | ||||
| 	if opaque { | ||||
| 		for y := dy - 1; y >= 0; y-- { | ||||
| 			min := y*stride + 0 | ||||
| 			max := y*stride + dx*4 | ||||
| 			off := 0 | ||||
| 			for i := min; i < max; i += 4 { | ||||
| 				buf[off+2] = pix[i+0] | ||||
| 				buf[off+1] = pix[i+1] | ||||
| 				buf[off+0] = pix[i+2] | ||||
| 				off += 3 | ||||
| 			} | ||||
| 			if _, err := w.Write(buf); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		for y := dy - 1; y >= 0; y-- { | ||||
| 			min := y*stride + 0 | ||||
| 			max := y*stride + dx*4 | ||||
| 			off := 0 | ||||
| 			for i := min; i < max; i += 4 { | ||||
| 				buf[off+2] = pix[i+0] | ||||
| 				buf[off+1] = pix[i+1] | ||||
| 				buf[off+0] = pix[i+2] | ||||
| 				buf[off+3] = pix[i+3] | ||||
| 				off += 4 | ||||
| 			} | ||||
| 			if _, err := w.Write(buf); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -105,6 +176,7 @@ func Encode(w io.Writer, m image.Image) error { | ||||
|  | ||||
| 	var step int | ||||
| 	var palette []byte | ||||
| 	var opaque bool | ||||
| 	switch m := m.(type) { | ||||
| 	case *image.Gray: | ||||
| 		step = (d.X + 3) &^ 3 | ||||
| @@ -134,6 +206,28 @@ func Encode(w io.Writer, m image.Image) error { | ||||
| 		h.fileSize += uint32(len(palette)) + h.imageSize | ||||
| 		h.pixOffset += uint32(len(palette)) | ||||
| 		h.bpp = 8 | ||||
| 	case *image.RGBA: | ||||
| 		opaque = m.Opaque() | ||||
| 		if opaque { | ||||
| 			step = (3*d.X + 3) &^ 3 | ||||
| 			h.bpp = 24 | ||||
| 		} else { | ||||
| 			step = 4 * d.X | ||||
| 			h.bpp = 32 | ||||
| 		} | ||||
| 		h.imageSize = uint32(d.Y * step) | ||||
| 		h.fileSize += h.imageSize | ||||
| 	case *image.NRGBA: | ||||
| 		opaque = m.Opaque() | ||||
| 		if opaque { | ||||
| 			step = (3*d.X + 3) &^ 3 | ||||
| 			h.bpp = 24 | ||||
| 		} else { | ||||
| 			step = 4 * d.X | ||||
| 			h.bpp = 32 | ||||
| 		} | ||||
| 		h.imageSize = uint32(d.Y * step) | ||||
| 		h.fileSize += h.imageSize | ||||
| 	default: | ||||
| 		step = (3*d.X + 3) &^ 3 | ||||
| 		h.imageSize = uint32(d.Y * step) | ||||
| @@ -160,7 +254,9 @@ func Encode(w io.Writer, m image.Image) error { | ||||
| 	case *image.Paletted: | ||||
| 		return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step) | ||||
| 	case *image.RGBA: | ||||
| 		return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step) | ||||
| 		return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) | ||||
| 	case *image.NRGBA: | ||||
| 		return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) | ||||
| 	} | ||||
| 	return encode(w, m, step) | ||||
| } | ||||
|   | ||||
							
								
								
									
										87
									
								
								vendor/golang.org/x/net/html/parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										87
									
								
								vendor/golang.org/x/net/html/parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -209,27 +209,6 @@ loop: | ||||
| 	p.oe = p.oe[:i+1] | ||||
| } | ||||
|  | ||||
| // generateAllImpliedEndTags pops nodes off the stack of open elements as long as | ||||
| // the top node has a tag name of caption, colgroup, dd, div, dt, li, optgroup, option, p, rb, | ||||
| // rp, rt, rtc, span, tbody, td, tfoot, th, thead or tr. | ||||
| func (p *parser) generateAllImpliedEndTags() { | ||||
| 	var i int | ||||
| 	for i = len(p.oe) - 1; i >= 0; i-- { | ||||
| 		n := p.oe[i] | ||||
| 		if n.Type == ElementNode { | ||||
| 			switch n.DataAtom { | ||||
| 			// TODO: remove this divergence from the HTML5 spec | ||||
| 			case a.Caption, a.Colgroup, a.Dd, a.Div, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, | ||||
| 				a.Rp, a.Rt, a.Rtc, a.Span, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		break | ||||
| 	} | ||||
|  | ||||
| 	p.oe = p.oe[:i+1] | ||||
| } | ||||
|  | ||||
| // addChild adds a child node n to the top element, and pushes n onto the stack | ||||
| // of open elements if it is an element node. | ||||
| func (p *parser) addChild(n *Node) { | ||||
| @@ -276,7 +255,7 @@ func (p *parser) fosterParent(n *Node) { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if template != nil && (table == nil || j < i) { | ||||
| 	if template != nil && (table == nil || j > i) { | ||||
| 		template.AppendChild(n) | ||||
| 		return | ||||
| 	} | ||||
| @@ -679,11 +658,16 @@ func inHeadIM(p *parser) bool { | ||||
| 			if !p.oe.contains(a.Template) { | ||||
| 				return true | ||||
| 			} | ||||
| 			p.generateAllImpliedEndTags() | ||||
| 			if n := p.oe.top(); n.DataAtom != a.Template { | ||||
| 				return true | ||||
| 			// TODO: remove this divergence from the HTML5 spec. | ||||
| 			// | ||||
| 			// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 | ||||
| 			p.generateImpliedEndTags() | ||||
| 			for i := len(p.oe) - 1; i >= 0; i-- { | ||||
| 				if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template { | ||||
| 					p.oe = p.oe[:i] | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			p.popUntil(defaultScope, a.Template) | ||||
| 			p.clearActiveFormattingElements() | ||||
| 			p.templateStack.pop() | ||||
| 			p.resetInsertionMode() | ||||
| @@ -860,9 +844,13 @@ func inBodyIM(p *parser) bool { | ||||
| 			// The newline, if any, will be dealt with by the TextToken case. | ||||
| 			p.framesetOK = false | ||||
| 		case a.Form: | ||||
| 			if p.oe.contains(a.Template) || p.form == nil { | ||||
| 			if p.form != nil && !p.oe.contains(a.Template) { | ||||
| 				// Ignore the token | ||||
| 				return true | ||||
| 			} | ||||
| 			p.popUntil(buttonScope, a.P) | ||||
| 			p.addElement() | ||||
| 			if !p.oe.contains(a.Template) { | ||||
| 				p.form = p.top() | ||||
| 			} | ||||
| 		case a.Li: | ||||
| @@ -1070,13 +1058,7 @@ func inBodyIM(p *parser) bool { | ||||
| 				p.acknowledgeSelfClosingTag() | ||||
| 			} | ||||
| 			return true | ||||
| 		case a.Frame: | ||||
| 			// TODO: remove this divergence from the HTML5 spec. | ||||
| 			if p.oe.contains(a.Template) { | ||||
| 				p.addElement() | ||||
| 				return true | ||||
| 			} | ||||
| 		case a.Caption, a.Col, a.Colgroup, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: | ||||
| 		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: | ||||
| 			// Ignore the token. | ||||
| 		default: | ||||
| 			p.reconstructActiveFormattingElements() | ||||
| @@ -1098,12 +1080,13 @@ func inBodyIM(p *parser) bool { | ||||
| 			p.popUntil(defaultScope, p.tok.DataAtom) | ||||
| 		case a.Form: | ||||
| 			if p.oe.contains(a.Template) { | ||||
| 				if !p.oe.contains(a.Form) { | ||||
| 				i := p.indexOfElementInScope(defaultScope, a.Form) | ||||
| 				if i == -1 { | ||||
| 					// Ignore the token. | ||||
| 					return true | ||||
| 				} | ||||
| 				p.generateImpliedEndTags() | ||||
| 				if p.tok.DataAtom == a.Form { | ||||
| 				if p.oe[i].DataAtom != a.Form { | ||||
| 					// Ignore the token. | ||||
| 					return true | ||||
| 				} | ||||
| @@ -1346,9 +1329,6 @@ func textIM(p *parser) bool { | ||||
| // Section 12.2.6.4.9. | ||||
| func inTableIM(p *parser) bool { | ||||
| 	switch p.tok.Type { | ||||
| 	case ErrorToken: | ||||
| 		// Stop parsing. | ||||
| 		return true | ||||
| 	case TextToken: | ||||
| 		p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1) | ||||
| 		switch p.oe.top().DataAtom { | ||||
| @@ -1443,6 +1423,8 @@ func inTableIM(p *parser) bool { | ||||
| 	case DoctypeToken: | ||||
| 		// Ignore the token. | ||||
| 		return true | ||||
| 	case ErrorToken: | ||||
| 		return inBodyIM(p) | ||||
| 	} | ||||
|  | ||||
| 	p.fosterParenting = true | ||||
| @@ -1545,6 +1527,8 @@ func inColumnGroupIM(p *parser) bool { | ||||
| 		case a.Template: | ||||
| 			return inHeadIM(p) | ||||
| 		} | ||||
| 	case ErrorToken: | ||||
| 		return inBodyIM(p) | ||||
| 	} | ||||
| 	if p.oe.top().DataAtom != a.Colgroup { | ||||
| 		return true | ||||
| @@ -1709,9 +1693,6 @@ func inCellIM(p *parser) bool { | ||||
| // Section 12.2.6.4.16. | ||||
| func inSelectIM(p *parser) bool { | ||||
| 	switch p.tok.Type { | ||||
| 	case ErrorToken: | ||||
| 		// Stop parsing. | ||||
| 		return true | ||||
| 	case TextToken: | ||||
| 		p.addText(strings.Replace(p.tok.Data, "\x00", "", -1)) | ||||
| 	case StartTagToken: | ||||
| @@ -1775,6 +1756,8 @@ func inSelectIM(p *parser) bool { | ||||
| 	case DoctypeToken: | ||||
| 		// Ignore the token. | ||||
| 		return true | ||||
| 	case ErrorToken: | ||||
| 		return inBodyIM(p) | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| @@ -1841,17 +1824,28 @@ func inTemplateIM(p *parser) bool { | ||||
| 			// Ignore the token. | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	case ErrorToken: | ||||
| 		if !p.oe.contains(a.Template) { | ||||
| 			// Ignore the token. | ||||
| 			return true | ||||
| 		} | ||||
| 	p.popUntil(defaultScope, a.Template) | ||||
| 		// TODO: remove this divergence from the HTML5 spec. | ||||
| 		// | ||||
| 		// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 | ||||
| 		p.generateImpliedEndTags() | ||||
| 		for i := len(p.oe) - 1; i >= 0; i-- { | ||||
| 			if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template { | ||||
| 				p.oe = p.oe[:i] | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		p.clearActiveFormattingElements() | ||||
| 		p.templateStack.pop() | ||||
| 		p.resetInsertionMode() | ||||
| 		return false | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Section 12.2.6.4.19. | ||||
| func afterBodyIM(p *parser) bool { | ||||
| @@ -1923,11 +1917,6 @@ func inFramesetIM(p *parser) bool { | ||||
| 			p.acknowledgeSelfClosingTag() | ||||
| 		case a.Noframes: | ||||
| 			return inHeadIM(p) | ||||
| 		case a.Template: | ||||
| 			// TODO: remove this divergence from the HTML5 spec. | ||||
| 			// | ||||
| 			// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 | ||||
| 			return inTemplateIM(p) | ||||
| 		} | ||||
| 	case EndTagToken: | ||||
| 		switch p.tok.DataAtom { | ||||
|   | ||||
							
								
								
									
										5
									
								
								vendor/gopkg.in/toast.v1/toast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/gopkg.in/toast.v1/toast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -11,6 +11,7 @@ import ( | ||||
| 	"text/template" | ||||
|  | ||||
| 	"github.com/nu7hatch/gouuid" | ||||
| 	"syscall" | ||||
| ) | ||||
|  | ||||
| var toastTemplate *template.Template | ||||
| @@ -347,7 +348,9 @@ func invokeTemporaryScript(content string) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err = exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file).Run(); err != nil { | ||||
| 	cmd := exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file) | ||||
| 	cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} | ||||
| 	if err = cmd.Run(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
|   | ||||
							
								
								
									
										131
									
								
								vendor/maunium.net/go/gomatrix/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								vendor/maunium.net/go/gomatrix/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,13 +6,16 @@ package gomatrix | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"maunium.net/go/maulogger" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"path" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
| @@ -26,6 +29,7 @@ type Client struct { | ||||
| 	Client        *http.Client // The underlying HTTP client which will be used to make HTTP requests. | ||||
| 	Syncer        Syncer       // The thing which can process /sync responses | ||||
| 	Store         Storer       // The thing which can store rooms/tokens/ids | ||||
| 	Logger        maulogger.Logger | ||||
|  | ||||
| 	// The ?user_id= query parameter for application services. This must be set *prior* to calling a method. If this is empty, | ||||
| 	// no user_id parameter will be sent. | ||||
| @@ -39,6 +43,7 @@ type Client struct { | ||||
| // HTTPError An HTTP Error response, which may wrap an underlying native Go Error. | ||||
| type HTTPError struct { | ||||
| 	WrappedError error | ||||
| 	RespError    *RespError | ||||
| 	Message      string | ||||
| 	Code         int | ||||
| } | ||||
| @@ -177,6 +182,14 @@ func (cli *Client) StopSync() { | ||||
| 	cli.incrementSyncingID() | ||||
| } | ||||
|  | ||||
| func (cli *Client) LogRequest(req *http.Request, body string) { | ||||
| 	if cli.Logger == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	cli.Logger.Debugfln("%s %s %s", req.Method, req.URL.Path, body) | ||||
| } | ||||
|  | ||||
| // MakeRequest makes a JSON HTTP request to the given URL. | ||||
| // If "resBody" is not nil, the response body will be json.Unmarshalled into it. | ||||
| // | ||||
| @@ -186,12 +199,14 @@ func (cli *Client) StopSync() { | ||||
| func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) { | ||||
| 	var req *http.Request | ||||
| 	var err error | ||||
| 	logBody := "{}" | ||||
| 	if reqBody != nil { | ||||
| 		var jsonStr []byte | ||||
| 		jsonStr, err = json.Marshal(reqBody) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		logBody = string(jsonStr) | ||||
| 		req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(jsonStr)) | ||||
| 	} else { | ||||
| 		req, err = http.NewRequest(method, httpURL, nil) | ||||
| @@ -201,6 +216,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{ | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req.Header.Set("Content-Type", "application/json") | ||||
| 	cli.LogRequest(req, logBody) | ||||
| 	res, err := cli.Client.Do(req) | ||||
| 	if res != nil { | ||||
| 		defer res.Body.Close() | ||||
| @@ -211,9 +227,11 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{ | ||||
| 	contents, err := ioutil.ReadAll(res.Body) | ||||
| 	if res.StatusCode/100 != 2 { // not 2xx | ||||
| 		var wrap error | ||||
| 		var respErr RespError | ||||
| 		if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" { | ||||
| 		respErr := &RespError{} | ||||
| 		if _ = json.Unmarshal(contents, respErr); respErr.ErrCode != "" { | ||||
| 			wrap = respErr | ||||
| 		} else { | ||||
| 			respErr = nil | ||||
| 		} | ||||
|  | ||||
| 		// If we failed to decode as RespError, don't just drop the HTTP body, include it in the | ||||
| @@ -227,6 +245,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{ | ||||
| 			Code:         res.StatusCode, | ||||
| 			Message:      msg, | ||||
| 			WrappedError: wrap, | ||||
| 			RespError:    respErr, | ||||
| 		} | ||||
| 	} | ||||
| 	if err != nil { | ||||
| @@ -442,17 +461,38 @@ func (cli *Client) SetAvatarURL(url string) (err error) { | ||||
|  | ||||
| // SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid | ||||
| // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal. | ||||
| func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error) { | ||||
| func (cli *Client) SendMessageEvent(roomID string, eventType EventType, contentJSON interface{}) (resp *RespSendEvent, err error) { | ||||
| 	txnID := txnID() | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "send", eventType, txnID) | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "send", eventType.String(), txnID) | ||||
| 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid | ||||
| // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal. | ||||
| func (cli *Client) SendMassagedMessageEvent(roomID string, eventType EventType, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) { | ||||
| 	txnID := txnID() | ||||
| 	urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "send", eventType.String(), txnID}, map[string]string{ | ||||
| 		"ts": strconv.FormatInt(ts, 10), | ||||
| 	}) | ||||
| 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey | ||||
| // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal. | ||||
| func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) { | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "state", eventType, stateKey) | ||||
| func (cli *Client) SendStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) { | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey) | ||||
| 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey | ||||
| // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal. | ||||
| func (cli *Client) SendMassagedStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) { | ||||
| 	urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "state", eventType.String(), stateKey}, map[string]string{ | ||||
| 		"ts": strconv.FormatInt(ts, 10), | ||||
| 	}) | ||||
| 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp) | ||||
| 	return | ||||
| } | ||||
| @@ -460,16 +500,17 @@ func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSO | ||||
| // SendText sends an m.room.message event into the given room with a msgtype of m.text | ||||
| // See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text | ||||
| func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) { | ||||
| 	return cli.SendMessageEvent(roomID, "m.room.message", | ||||
| 		TextMessage{"m.text", text}) | ||||
| 	return cli.SendMessageEvent(roomID, EventMessage, Content{ | ||||
| 		MsgType: MsgText, | ||||
| 		Body:    text, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // SendImage sends an m.room.message event into the given room with a msgtype of m.image | ||||
| // See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-image | ||||
| func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) { | ||||
| 	return cli.SendMessageEvent(roomID, "m.room.message", | ||||
| 		ImageMessage{ | ||||
| 			MsgType: "m.image", | ||||
| 	return cli.SendMessageEvent(roomID, EventMessage, Content{ | ||||
| 		MsgType: MsgImage, | ||||
| 		Body:    body, | ||||
| 		URL:     url, | ||||
| 	}) | ||||
| @@ -478,9 +519,8 @@ func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) { | ||||
| // SendVideo sends an m.room.message event into the given room with a msgtype of m.video | ||||
| // See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-video | ||||
| func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) { | ||||
| 	return cli.SendMessageEvent(roomID, "m.room.message", | ||||
| 		VideoMessage{ | ||||
| 			MsgType: "m.video", | ||||
| 	return cli.SendMessageEvent(roomID, EventMessage, Content{ | ||||
| 		MsgType: MsgVideo, | ||||
| 		Body:    body, | ||||
| 		URL:     url, | ||||
| 	}) | ||||
| @@ -489,8 +529,10 @@ func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) { | ||||
| // SendNotice sends an m.room.message event into the given room with a msgtype of m.notice | ||||
| // See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice | ||||
| func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) { | ||||
| 	return cli.SendMessageEvent(roomID, "m.room.message", | ||||
| 		TextMessage{"m.notice", text}) | ||||
| 	return cli.SendMessageEvent(roomID, EventMessage, Content{ | ||||
| 		MsgType: MsgNotice, | ||||
| 		Body:    text, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid | ||||
| @@ -569,11 +611,18 @@ func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp * | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (cli *Client) SetPresence(status string) (err error) { | ||||
| 	req := ReqPresence{Presence: status} | ||||
| 	u := cli.BuildURL("presence", cli.UserID, "status") | ||||
| 	_, err = cli.MakeRequest("PUT", u, req, nil) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // StateEvent gets a single state event in a room. It will attempt to JSON unmarshal into the given "outContent" struct with | ||||
| // the HTTP response body, or return an error. | ||||
| // See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey | ||||
| func (cli *Client) StateEvent(roomID, eventType, stateKey string, outContent interface{}) (err error) { | ||||
| 	u := cli.BuildURL("rooms", roomID, "state", eventType, stateKey) | ||||
| func (cli *Client) StateEvent(roomID string, eventType EventType, stateKey string, outContent interface{}) (err error) { | ||||
| 	u := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey) | ||||
| 	_, err = cli.MakeRequest("GET", u, nil, outContent) | ||||
| 	return | ||||
| } | ||||
| @@ -587,18 +636,48 @@ func (cli *Client) UploadLink(link string) (*RespMediaUpload, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return cli.UploadToContentRepo(res.Body, res.Header.Get("Content-Type"), res.ContentLength) | ||||
| 	return cli.Upload(res.Body, res.Header.Get("Content-Type"), res.ContentLength) | ||||
| } | ||||
|  | ||||
| func (cli *Client) Download(mxcURL string) (io.ReadCloser, error) { | ||||
| 	if !strings.HasPrefix(mxcURL, "mxc://") { | ||||
| 		return nil, errors.New("invalid Matrix content URL") | ||||
| 	} | ||||
| 	parts := strings.Split(mxcURL[len("mxc://"):], "/") | ||||
| 	if len(parts) != 2 { | ||||
| 		return nil, errors.New("invalid Matrix content URL") | ||||
| 	} | ||||
| 	u := cli.BuildBaseURL("_matrix/media/r0/download", parts[0], parts[1]) | ||||
| 	resp, err := cli.Client.Get(u) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return resp.Body, nil | ||||
| } | ||||
|  | ||||
| func (cli *Client) DownloadBytes(mxcURL string) ([]byte, error) { | ||||
| 	resp, err := cli.Download(mxcURL) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Close() | ||||
| 	return ioutil.ReadAll(resp) | ||||
| } | ||||
|  | ||||
| func (cli *Client) UploadBytes(data []byte, contentType string) (*RespMediaUpload, error) { | ||||
| 	return cli.Upload(bytes.NewReader(data), contentType, int64(len(data))) | ||||
| } | ||||
|  | ||||
| // UploadToContentRepo uploads the given bytes to the content repository and returns an MXC URI. | ||||
| // See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-media-r0-upload | ||||
| func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) { | ||||
| func (cli *Client) Upload(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) { | ||||
| 	req, err := http.NewRequest("POST", cli.BuildBaseURL("_matrix/media/r0/upload"), content) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req.Header.Set("Content-Type", contentType) | ||||
| 	req.ContentLength = contentLength | ||||
| 	cli.LogRequest(req, fmt.Sprintf("%d bytes", contentLength)) | ||||
| 	res, err := cli.Client.Do(req) | ||||
| 	if res != nil { | ||||
| 		defer res.Body.Close() | ||||
| @@ -666,6 +745,18 @@ func (cli *Client) Messages(roomID, from, to string, dir rune, limit int) (resp | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (cli *Client) GetEvent(roomID, eventID string) (resp *Event, err error) { | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "event", eventID) | ||||
| 	_, err = cli.MakeRequest("GET", urlPath, nil, &resp) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (cli *Client) MarkRead(roomID, eventID string) (err error) { | ||||
| 	urlPath := cli.BuildURL("rooms", roomID, "receipt", "m.read", eventID) | ||||
| 	_, err = cli.MakeRequest("POST", urlPath, struct{}{}, nil) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // TurnServer returns turn server details and credentials for the client to use when initiating calls. | ||||
| // See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver | ||||
| func (cli *Client) TurnServer() (resp *RespTurnServer, err error) { | ||||
|   | ||||
							
								
								
									
										441
									
								
								vendor/maunium.net/go/gomatrix/events.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										441
									
								
								vendor/maunium.net/go/gomatrix/events.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,110 +1,413 @@ | ||||
| package gomatrix | ||||
|  | ||||
| import ( | ||||
| 	"html" | ||||
| 	"regexp" | ||||
| 	"encoding/json" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
|  | ||||
| type EventTypeClass int | ||||
|  | ||||
| const ( | ||||
| 	// Normal message events | ||||
| 	MessageEventType EventTypeClass = iota | ||||
| 	// State events | ||||
| 	StateEventType | ||||
| 	// Ephemeral events | ||||
| 	EphemeralEventType | ||||
| 	// Account data events | ||||
| 	AccountDataEventType | ||||
| 	// Unknown events | ||||
| 	UnknownEventType | ||||
| ) | ||||
|  | ||||
| type EventType struct { | ||||
| 	Type  string | ||||
| 	Class EventTypeClass | ||||
| } | ||||
|  | ||||
| func NewEventType(name string) EventType { | ||||
| 	evtType := EventType{Type: name} | ||||
| 	evtType.Class = evtType.GuessClass() | ||||
| 	return evtType | ||||
| } | ||||
|  | ||||
| func (et *EventType) IsState() bool { | ||||
| 	return et.Class == StateEventType | ||||
| } | ||||
|  | ||||
| func (et *EventType) IsEphemeral() bool { | ||||
| 	return et.Class == EphemeralEventType | ||||
| } | ||||
|  | ||||
| func (et *EventType) IsCustom() bool { | ||||
| 	return !strings.HasPrefix(et.Type, "m.") | ||||
| } | ||||
|  | ||||
| func (et *EventType) GuessClass() EventTypeClass { | ||||
| 	switch et.Type { | ||||
| 	case StateAliases.Type, StateCanonicalAlias.Type, StateCreate.Type, StateJoinRules.Type, StateMember.Type, | ||||
| 		StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateTopic.Type, StatePinnedEvents.Type: | ||||
| 		return StateEventType | ||||
| 	case EphemeralEventReceipt.Type, EphemeralEventTyping.Type: | ||||
| 		return EphemeralEventType | ||||
| 	case AccountDataDirectChats.Type, AccountDataPushRules.Type, AccountDataRoomTags.Type: | ||||
| 		return AccountDataEventType | ||||
| 	case EventRedaction.Type, EventMessage.Type, EventSticker.Type: | ||||
| 		return MessageEventType | ||||
| 	default: | ||||
| 		return UnknownEventType | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (et *EventType) UnmarshalJSON(data []byte) error { | ||||
| 	err := json.Unmarshal(data, &et.Type) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	et.Class = et.GuessClass() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (et *EventType) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(&et.Type) | ||||
| } | ||||
|  | ||||
| func (et *EventType) String() string { | ||||
| 	return et.Type | ||||
| } | ||||
|  | ||||
| // State events | ||||
| var ( | ||||
| 	StateAliases        = EventType{"m.room.aliases", StateEventType} | ||||
| 	StateCanonicalAlias = EventType{"m.room.canonical_alias", StateEventType} | ||||
| 	StateCreate         = EventType{"m.room.create", StateEventType} | ||||
| 	StateJoinRules      = EventType{"m.room.join_rules", StateEventType} | ||||
| 	StateMember         = EventType{"m.room.member", StateEventType} | ||||
| 	StatePowerLevels    = EventType{"m.room.power_levels", StateEventType} | ||||
| 	StateRoomName       = EventType{"m.room.name", StateEventType} | ||||
| 	StateTopic          = EventType{"m.room.topic", StateEventType} | ||||
| 	StateRoomAvatar     = EventType{"m.room.avatar", StateEventType} | ||||
| 	StatePinnedEvents   = EventType{"m.room.pinned_events", StateEventType} | ||||
| ) | ||||
|  | ||||
| // Message events | ||||
| var ( | ||||
| 	EventRedaction = EventType{"m.room.redaction", MessageEventType} | ||||
| 	EventMessage   = EventType{"m.room.message", MessageEventType} | ||||
| 	EventSticker   = EventType{"m.sticker", MessageEventType} | ||||
| ) | ||||
|  | ||||
| // Ephemeral events | ||||
| var ( | ||||
| 	EphemeralEventReceipt = EventType{"m.receipt", EphemeralEventType} | ||||
| 	EphemeralEventTyping  = EventType{"m.receipt", EphemeralEventType} | ||||
| ) | ||||
|  | ||||
| // Account data events | ||||
| var ( | ||||
| 	AccountDataDirectChats = EventType{"m.direct", AccountDataEventType} | ||||
| 	AccountDataPushRules   = EventType{"m.push_rules", AccountDataEventType} | ||||
| 	AccountDataRoomTags    = EventType{"m.tag", AccountDataEventType} | ||||
| ) | ||||
|  | ||||
| type MessageType string | ||||
|  | ||||
| // Msgtypes | ||||
| const ( | ||||
| 	MsgText     MessageType = "m.text" | ||||
| 	MsgEmote                = "m.emote" | ||||
| 	MsgNotice               = "m.notice" | ||||
| 	MsgImage                = "m.image" | ||||
| 	MsgLocation             = "m.location" | ||||
| 	MsgVideo                = "m.video" | ||||
| 	MsgAudio                = "m.audio" | ||||
| 	MsgFile                 = "m.file" | ||||
| ) | ||||
|  | ||||
| type Format string | ||||
|  | ||||
| // Message formats | ||||
| const ( | ||||
| 	FormatHTML Format = "org.matrix.custom.html" | ||||
| ) | ||||
|  | ||||
| // Event represents a single Matrix event. | ||||
| type Event struct { | ||||
| 	StateKey  *string   `json:"state_key,omitempty"` // The state key for the event. Only present on State Events. | ||||
| 	Sender    string    `json:"sender"`              // The user ID of the sender of the event | ||||
| 	Type      string                 `json:"type"`                // The event type | ||||
| 	Type      EventType `json:"type"`                // The event type | ||||
| 	Timestamp int64     `json:"origin_server_ts"`    // The unix timestamp when this message was sent by the origin server | ||||
| 	ID        string    `json:"event_id"`            // The unique ID of this event | ||||
| 	RoomID    string    `json:"room_id"`             // The room the event was sent to. May be nil (e.g. for presence) | ||||
| 	Content   map[string]interface{} `json:"content"`             // The JSON content of the event. | ||||
| 	Content   Content   `json:"content"`             // The JSON content of the event. | ||||
| 	Redacts   string    `json:"redacts,omitempty"`   // The event ID that was redacted if a m.room.redaction event | ||||
| 	Unsigned  Unsigned  `json:"unsigned,omitempty"`  // Unsigned content set by own homeserver. | ||||
|  | ||||
| 	InviteRoomState []StrippedState `json:"invite_room_state"` | ||||
| } | ||||
|  | ||||
| func (evt *Event) GetStateKey() string { | ||||
| 	if evt.StateKey != nil { | ||||
| 		return *evt.StateKey | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type StrippedState struct { | ||||
| 	Content  Content   `json:"content"` | ||||
| 	Type     EventType `json:"type"` | ||||
| 	StateKey string    `json:"state_key"` | ||||
| } | ||||
|  | ||||
| type Unsigned struct { | ||||
| 	PrevContent   map[string]interface{} `json:"prev_content,omitempty"` | ||||
| 	PrevContent   *Content `json:"prev_content,omitempty"` | ||||
| 	PrevSender    string   `json:"prev_sender,omitempty"` | ||||
| 	ReplacesState string   `json:"replaces_state,omitempty"` | ||||
| 	Age           int64                  `json:"age"` | ||||
| 	Age           int64    `json:"age,omitempty"` | ||||
| } | ||||
|  | ||||
| // Body returns the value of the "body" key in the event content if it is | ||||
| // present and is a string. | ||||
| func (event *Event) Body() (body string, ok bool) { | ||||
| 	value, exists := event.Content["body"] | ||||
| 	if !exists { | ||||
| 		return | ||||
| type Content struct { | ||||
| 	VeryRaw json.RawMessage        `json:"-"` | ||||
| 	Raw     map[string]interface{} `json:"-"` | ||||
|  | ||||
| 	MsgType       MessageType `json:"msgtype,omitempty"` | ||||
| 	Body          string      `json:"body,omitempty"` | ||||
| 	Format        Format      `json:"format,omitempty"` | ||||
| 	FormattedBody string      `json:"formatted_body,omitempty"` | ||||
|  | ||||
| 	Info *FileInfo `json:"info,omitempty"` | ||||
| 	URL  string    `json:"url,omitempty"` | ||||
|  | ||||
| 	// Membership key for easy access in m.room.member events | ||||
| 	Membership Membership `json:"membership,omitempty"` | ||||
|  | ||||
| 	RelatesTo *RelatesTo `json:"m.relates_to,omitempty"` | ||||
|  | ||||
| 	PowerLevels | ||||
| 	Member | ||||
| 	Aliases []string `json:"aliases,omitempty"` | ||||
| 	CanonicalAlias | ||||
| 	RoomName | ||||
| 	RoomTopic | ||||
|  | ||||
| 	RoomTags      Tags     `json:"tags,omitempty"` | ||||
| 	TypingUserIDs []string `json:"user_ids,omitempty"` | ||||
| } | ||||
| 	body, ok = value.(string) | ||||
|  | ||||
| type serializableContent Content | ||||
|  | ||||
| func (content *Content) UnmarshalJSON(data []byte) error { | ||||
| 	content.VeryRaw = data | ||||
| 	if err := json.Unmarshal(data, &content.Raw); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return json.Unmarshal(data, (*serializableContent)(content)) | ||||
| } | ||||
|  | ||||
| func (content *Content) UnmarshalPowerLevels() (pl PowerLevels, err error) { | ||||
| 	err = json.Unmarshal(content.VeryRaw, &pl) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // MessageType returns the value of the "msgtype" key in the event content if | ||||
| // it is present and is a string. | ||||
| func (event *Event) MessageType() (msgtype string, ok bool) { | ||||
| 	value, exists := event.Content["msgtype"] | ||||
| 	if !exists { | ||||
| 		return | ||||
| 	} | ||||
| 	msgtype, ok = value.(string) | ||||
| func (content *Content) UnmarshalMember() (m Member, err error) { | ||||
| 	err = json.Unmarshal(content.VeryRaw, &m) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // TextMessage is the contents of a Matrix formated message event. | ||||
| type TextMessage struct { | ||||
| 	MsgType string `json:"msgtype"` | ||||
| 	Body    string `json:"body"` | ||||
| func (content *Content) UnmarshalCanonicalAlias() (ca CanonicalAlias, err error) { | ||||
| 	err = json.Unmarshal(content.VeryRaw, &ca) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image | ||||
| type ImageInfo struct { | ||||
| 	Height   uint   `json:"h,omitempty"` | ||||
| 	Width    uint   `json:"w,omitempty"` | ||||
| 	Mimetype string `json:"mimetype,omitempty"` | ||||
| 	Size     uint   `json:"size,omitempty"` | ||||
| func (content *Content) GetInfo() *FileInfo { | ||||
| 	if content.Info == nil { | ||||
| 		content.Info = &FileInfo{} | ||||
| 	} | ||||
| 	return content.Info | ||||
| } | ||||
|  | ||||
| // VideoInfo contains info about a video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video | ||||
| type VideoInfo struct { | ||||
| 	Mimetype      string    `json:"mimetype,omitempty"` | ||||
| 	ThumbnailInfo ImageInfo `json:"thumbnail_info"` | ||||
| type Tags map[string]struct { | ||||
| 	Order string `json:"order"` | ||||
| } | ||||
|  | ||||
| type RoomName struct { | ||||
| 	Name string `json:"name,omitempty"` | ||||
| } | ||||
|  | ||||
| type RoomTopic struct { | ||||
| 	Topic string `json:"topic,omitempty"` | ||||
| } | ||||
|  | ||||
| // Membership is an enum specifying the membership state of a room member. | ||||
| type Membership string | ||||
|  | ||||
| // The allowed membership states as specified in spec section 10.5.5. | ||||
| const ( | ||||
| 	MembershipJoin   Membership = "join" | ||||
| 	MembershipLeave  Membership = "leave" | ||||
| 	MembershipInvite Membership = "invite" | ||||
| 	MembershipBan    Membership = "ban" | ||||
| 	MembershipKnock  Membership = "knock" | ||||
| ) | ||||
|  | ||||
| type Member struct { | ||||
| 	Membership       Membership        `json:"membership,omitempty"` | ||||
| 	AvatarURL        string            `json:"avatar_url,omitempty"` | ||||
| 	Displayname      string            `json:"displayname,omitempty"` | ||||
| 	ThirdPartyInvite *ThirdPartyInvite `json:"third_party_invite,omitempty"` | ||||
| 	Reason           string            `json:"reason,omitempty"` | ||||
| } | ||||
|  | ||||
| type ThirdPartyInvite struct { | ||||
| 	DisplayName string `json:"display_name"` | ||||
| 	Signed      struct { | ||||
| 		Token      string          `json:"token"` | ||||
| 		Signatures json.RawMessage `json:"signatures"` | ||||
| 		MXID       string          `json:"mxid"` | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type CanonicalAlias struct { | ||||
| 	Alias string `json:"alias,omitempty"` | ||||
| } | ||||
|  | ||||
| type PowerLevels struct { | ||||
| 	usersLock    sync.RWMutex   `json:"-"` | ||||
| 	Users        map[string]int `json:"users,omitempty"` | ||||
| 	UsersDefault int            `json:"users_default,omitempty"` | ||||
|  | ||||
| 	eventsLock    sync.RWMutex   `json:"-"` | ||||
| 	Events        map[string]int `json:"events,omitempty"` | ||||
| 	EventsDefault int            `json:"events_default,omitempty"` | ||||
|  | ||||
| 	StateDefaultPtr *int `json:"state_default,omitempty"` | ||||
|  | ||||
| 	InvitePtr *int `json:"invite,omitempty"` | ||||
| 	KickPtr   *int `json:"kick,omitempty"` | ||||
| 	BanPtr    *int `json:"ban,omitempty"` | ||||
| 	RedactPtr *int `json:"redact,omitempty"` | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) Invite() int { | ||||
| 	if pl.InvitePtr != nil { | ||||
| 		return *pl.InvitePtr | ||||
| 	} | ||||
| 	return 50 | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) Kick() int { | ||||
| 	if pl.KickPtr != nil { | ||||
| 		return *pl.KickPtr | ||||
| 	} | ||||
| 	return 50 | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) Ban() int { | ||||
| 	if pl.BanPtr != nil { | ||||
| 		return *pl.BanPtr | ||||
| 	} | ||||
| 	return 50 | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) Redact() int { | ||||
| 	if pl.RedactPtr != nil { | ||||
| 		return *pl.RedactPtr | ||||
| 	} | ||||
| 	return 50 | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) StateDefault() int { | ||||
| 	if pl.StateDefaultPtr != nil { | ||||
| 		return *pl.StateDefaultPtr | ||||
| 	} | ||||
| 	return 50 | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) GetUserLevel(userID string) int { | ||||
| 	pl.usersLock.RLock() | ||||
| 	defer pl.usersLock.RUnlock() | ||||
| 	level, ok := pl.Users[userID] | ||||
| 	if !ok { | ||||
| 		return pl.UsersDefault | ||||
| 	} | ||||
| 	return level | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) SetUserLevel(userID string, level int) { | ||||
| 	pl.usersLock.Lock() | ||||
| 	defer pl.usersLock.Unlock() | ||||
| 	if level == pl.UsersDefault { | ||||
| 		delete(pl.Users, userID) | ||||
| 	} else { | ||||
| 		pl.Users[userID] = level | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) EnsureUserLevel(userID string, level int) bool { | ||||
| 	existingLevel := pl.GetUserLevel(userID) | ||||
| 	if existingLevel != level { | ||||
| 		pl.SetUserLevel(userID, level) | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) GetEventLevel(eventType EventType) int { | ||||
| 	pl.eventsLock.RLock() | ||||
| 	defer pl.eventsLock.RUnlock() | ||||
| 	level, ok := pl.Events[eventType.String()] | ||||
| 	if !ok { | ||||
| 		if eventType.IsState() { | ||||
| 			return pl.StateDefault() | ||||
| 		} | ||||
| 		return pl.EventsDefault | ||||
| 	} | ||||
| 	return level | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) SetEventLevel(eventType EventType, level int) { | ||||
| 	pl.eventsLock.Lock() | ||||
| 	defer pl.eventsLock.Unlock() | ||||
| 	if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) { | ||||
| 		delete(pl.Events, eventType.String()) | ||||
| 	} else { | ||||
| 		pl.Events[eventType.String()] = level | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (pl *PowerLevels) EnsureEventLevel(eventType EventType, level int) bool { | ||||
| 	existingLevel := pl.GetEventLevel(eventType) | ||||
| 	if existingLevel != level { | ||||
| 		pl.SetEventLevel(eventType, level) | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type FileInfo struct { | ||||
| 	MimeType      string    `json:"mimetype,omitempty"` | ||||
| 	ThumbnailInfo *FileInfo `json:"thumbnail_info,omitempty"` | ||||
| 	ThumbnailURL  string    `json:"thumbnail_url,omitempty"` | ||||
| 	Height        uint      `json:"h,omitempty"` | ||||
| 	Width         uint      `json:"w,omitempty"` | ||||
| 	Height        int       `json:"h,omitempty"` | ||||
| 	Width         int       `json:"w,omitempty"` | ||||
| 	Duration      uint      `json:"duration,omitempty"` | ||||
| 	Size          uint      `json:"size,omitempty"` | ||||
| 	Size          int       `json:"size,omitempty"` | ||||
| } | ||||
|  | ||||
| // VideoMessage is an m.video  - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video | ||||
| type VideoMessage struct { | ||||
| 	MsgType string    `json:"msgtype"` | ||||
| 	Body    string    `json:"body"` | ||||
| 	URL     string    `json:"url"` | ||||
| 	Info    VideoInfo `json:"info"` | ||||
| func (fileInfo *FileInfo) GetThumbnailInfo() *FileInfo { | ||||
| 	if fileInfo.ThumbnailInfo == nil { | ||||
| 		fileInfo.ThumbnailInfo = &FileInfo{} | ||||
| 	} | ||||
| 	return fileInfo.ThumbnailInfo | ||||
| } | ||||
|  | ||||
| // ImageMessage is an m.image event | ||||
| type ImageMessage struct { | ||||
| 	MsgType string    `json:"msgtype"` | ||||
| 	Body    string    `json:"body"` | ||||
| 	URL     string    `json:"url"` | ||||
| 	Info    ImageInfo `json:"info"` | ||||
| type RelatesTo struct { | ||||
| 	InReplyTo InReplyTo `json:"m.in_reply_to,omitempty"` | ||||
| } | ||||
|  | ||||
| // An HTMLMessage is the contents of a Matrix HTML formated message event. | ||||
| type HTMLMessage struct { | ||||
| 	Body          string `json:"body"` | ||||
| 	MsgType       string `json:"msgtype"` | ||||
| 	Format        string `json:"format"` | ||||
| 	FormattedBody string `json:"formatted_body"` | ||||
| } | ||||
|  | ||||
| var htmlRegex = regexp.MustCompile("<[^<]+?>") | ||||
|  | ||||
| // GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition | ||||
| // to the provided HTML. | ||||
| func GetHTMLMessage(msgtype, htmlText string) HTMLMessage { | ||||
| 	return HTMLMessage{ | ||||
| 		Body:          html.UnescapeString(htmlRegex.ReplaceAllLiteralString(htmlText, "")), | ||||
| 		MsgType:       msgtype, | ||||
| 		Format:        "org.matrix.custom.html", | ||||
| 		FormattedBody: htmlText, | ||||
| 	} | ||||
| type InReplyTo struct { | ||||
| 	EventID string `json:"event_id,omitempty"` | ||||
| 	// Not required, just for future-proofing | ||||
| 	RoomID string `json:"room_id,omitempty"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										96
									
								
								vendor/maunium.net/go/gomatrix/reply.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								vendor/maunium.net/go/gomatrix/reply.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| package gomatrix | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"golang.org/x/net/html" | ||||
| ) | ||||
|  | ||||
| var HTMLReplyFallbackRegex = regexp.MustCompile(`^<mx-reply>[\s\S]+?</mx-reply>`) | ||||
|  | ||||
| func TrimReplyFallbackHTML(html string) string { | ||||
| 	return HTMLReplyFallbackRegex.ReplaceAllString(html, "") | ||||
| } | ||||
|  | ||||
| func TrimReplyFallbackText(text string) string { | ||||
| 	if !strings.HasPrefix(text, "> ") || !strings.Contains(text, "\n") { | ||||
| 		return text | ||||
| 	} | ||||
|  | ||||
| 	lines := strings.Split(text, "\n") | ||||
| 	for len(lines) > 0 && strings.HasPrefix(lines[0], "> ") { | ||||
| 		lines = lines[1:] | ||||
| 	} | ||||
| 	return strings.TrimSpace(strings.Join(lines, "\n")) | ||||
| } | ||||
|  | ||||
| func (content *Content) RemoveReplyFallback() { | ||||
| 	if len(content.GetReplyTo()) > 0 { | ||||
| 		if content.Format == FormatHTML { | ||||
| 			content.FormattedBody = TrimReplyFallbackHTML(content.FormattedBody) | ||||
| 		} | ||||
| 		content.Body = TrimReplyFallbackText(content.Body) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (content *Content) GetReplyTo() string { | ||||
| 	if content.RelatesTo != nil { | ||||
| 		return content.RelatesTo.InReplyTo.EventID | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| const ReplyFormat = `<mx-reply><blockquote> | ||||
| <a href="https://matrix.to/#/%s/%s">In reply to</a> | ||||
| <a href="https://matrix.to/#/%s">%s</a> | ||||
| %s | ||||
| </blockquote></mx-reply> | ||||
| ` | ||||
|  | ||||
| func (evt *Event) GenerateReplyFallbackHTML() string { | ||||
| 	body := evt.Content.FormattedBody | ||||
| 	if len(body) == 0 { | ||||
| 		body = html.EscapeString(evt.Content.Body) | ||||
| 	} | ||||
|  | ||||
| 	senderDisplayName := evt.Sender | ||||
|  | ||||
| 	return fmt.Sprintf(ReplyFormat, evt.RoomID, evt.ID, evt.Sender, senderDisplayName, body) | ||||
| } | ||||
|  | ||||
| func (evt *Event) GenerateReplyFallbackText() string { | ||||
| 	body := evt.Content.Body | ||||
| 	lines := strings.Split(strings.TrimSpace(body), "\n") | ||||
| 	firstLine, lines := lines[0], lines[1:] | ||||
|  | ||||
| 	senderDisplayName := evt.Sender | ||||
|  | ||||
| 	var fallbackText strings.Builder | ||||
| 	fmt.Fprintf(&fallbackText, "> <%s> %s", senderDisplayName, firstLine) | ||||
| 	for _, line := range lines { | ||||
| 		fmt.Fprintf(&fallbackText, "\n> %s", line) | ||||
| 	} | ||||
| 	fallbackText.WriteString("\n\n") | ||||
| 	return fallbackText.String() | ||||
| } | ||||
|  | ||||
| func (content *Content) SetReply(inReplyTo *Event) { | ||||
| 	if content.RelatesTo == nil { | ||||
| 		content.RelatesTo = &RelatesTo{} | ||||
| 	} | ||||
| 	content.RelatesTo.InReplyTo = InReplyTo{ | ||||
| 		EventID: inReplyTo.ID, | ||||
| 		RoomID:  inReplyTo.RoomID, | ||||
| 	} | ||||
|  | ||||
| 	if content.MsgType == MsgText || content.MsgType == MsgNotice { | ||||
| 		if len(content.FormattedBody) == 0 || content.Format != FormatHTML { | ||||
| 			content.FormattedBody = html.EscapeString(content.Body) | ||||
| 			content.Format = FormatHTML | ||||
| 		} | ||||
| 		content.FormattedBody = inReplyTo.GenerateReplyFallbackHTML() + content.FormattedBody | ||||
| 		content.Body = inReplyTo.GenerateReplyFallbackText() + content.Body | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/maunium.net/go/gomatrix/requests.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/maunium.net/go/gomatrix/requests.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -31,7 +31,7 @@ type ReqCreateRoom struct { | ||||
| 	Invite          []string               `json:"invite,omitempty"` | ||||
| 	Invite3PID      []ReqInvite3PID        `json:"invite_3pid,omitempty"` | ||||
| 	CreationContent map[string]interface{} `json:"creation_content,omitempty"` | ||||
| 	InitialState    []Event                `json:"initial_state,omitempty"` | ||||
| 	InitialState    []*Event                `json:"initial_state,omitempty"` | ||||
| 	Preset          string                 `json:"preset,omitempty"` | ||||
| 	IsDirect        bool                   `json:"is_direct,omitempty"` | ||||
| } | ||||
| @@ -74,5 +74,9 @@ type ReqUnbanUser struct { | ||||
| // ReqTyping is the JSON request for https://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-typing-userid | ||||
| type ReqTyping struct { | ||||
| 	Typing  bool  `json:"typing"` | ||||
| 	Timeout int64 `json:"timeout"` | ||||
| 	Timeout int64 `json:"timeout,omitempty"` | ||||
| } | ||||
|  | ||||
| type ReqPresence struct { | ||||
| 	Presence string `json:"presence"` | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/maunium.net/go/gomatrix/responses.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/maunium.net/go/gomatrix/responses.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -64,7 +64,7 @@ type RespJoinedMembers struct { | ||||
| // RespMessages is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages | ||||
| type RespMessages struct { | ||||
| 	Start string  `json:"start"` | ||||
| 	Chunk []Event `json:"chunk"` | ||||
| 	Chunk []*Event `json:"chunk"` | ||||
| 	End   string  `json:"end"` | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										20
									
								
								vendor/maunium.net/go/gomatrix/room.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/maunium.net/go/gomatrix/room.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ package gomatrix | ||||
| // Room represents a single Matrix room. | ||||
| type Room struct { | ||||
| 	ID    string | ||||
| 	State map[string]map[string]*Event | ||||
| 	State map[EventType]map[string]*Event | ||||
| } | ||||
|  | ||||
| // UpdateState updates the room's current state with the given Event. This will clobber events based | ||||
| @@ -17,7 +17,7 @@ func (room Room) UpdateState(event *Event) { | ||||
| } | ||||
|  | ||||
| // GetStateEvent returns the state event for the given type/state_key combo, or nil. | ||||
| func (room Room) GetStateEvent(eventType string, stateKey string) *Event { | ||||
| func (room Room) GetStateEvent(eventType EventType, stateKey string) *Event { | ||||
| 	stateEventMap, _ := room.State[eventType] | ||||
| 	event, _ := stateEventMap[stateKey] | ||||
| 	return event | ||||
| @@ -25,17 +25,11 @@ func (room Room) GetStateEvent(eventType string, stateKey string) *Event { | ||||
|  | ||||
| // GetMembershipState returns the membership state of the given user ID in this room. If there is | ||||
| // no entry for this member, 'leave' is returned for consistency with left users. | ||||
| func (room Room) GetMembershipState(userID string) string { | ||||
| 	state := "leave" | ||||
| 	event := room.GetStateEvent("m.room.member", userID) | ||||
| func (room Room) GetMembershipState(userID string) Membership { | ||||
| 	state := MembershipLeave | ||||
| 	event := room.GetStateEvent(StateMember, userID) | ||||
| 	if event != nil { | ||||
| 		membershipState, found := event.Content["membership"] | ||||
| 		if found { | ||||
| 			mState, isString := membershipState.(string) | ||||
| 			if isString { | ||||
| 				state = mState | ||||
| 			} | ||||
| 		} | ||||
| 		state = event.Content.Membership | ||||
| 	} | ||||
| 	return state | ||||
| } | ||||
| @@ -45,6 +39,6 @@ func NewRoom(roomID string) *Room { | ||||
| 	// Init the State map and return a pointer to the Room | ||||
| 	return &Room{ | ||||
| 		ID:    roomID, | ||||
| 		State: make(map[string]map[string]*Event), | ||||
| 		State: make(map[EventType]map[string]*Event), | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										15
									
								
								vendor/maunium.net/go/gomatrix/sync.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/maunium.net/go/gomatrix/sync.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,7 +25,7 @@ type Syncer interface { | ||||
| type DefaultSyncer struct { | ||||
| 	UserID    string | ||||
| 	Store     Storer | ||||
| 	listeners map[string][]OnEventListener // event type to listeners array | ||||
| 	listeners map[EventType][]OnEventListener // event type to listeners array | ||||
| } | ||||
|  | ||||
| // OnEventListener can be used with DefaultSyncer.OnEventType to be informed of incoming events. | ||||
| @@ -36,7 +36,7 @@ func NewDefaultSyncer(userID string, store Storer) *DefaultSyncer { | ||||
| 	return &DefaultSyncer{ | ||||
| 		UserID:    userID, | ||||
| 		Store:     store, | ||||
| 		listeners: make(map[string][]OnEventListener), | ||||
| 		listeners: make(map[EventType][]OnEventListener), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -88,7 +88,7 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error) | ||||
|  | ||||
| // OnEventType allows callers to be notified when there are new events for the given event type. | ||||
| // There are no duplicate checks. | ||||
| func (s *DefaultSyncer) OnEventType(eventType string, callback OnEventListener) { | ||||
| func (s *DefaultSyncer) OnEventType(eventType EventType, callback OnEventListener) { | ||||
| 	_, exists := s.listeners[eventType] | ||||
| 	if !exists { | ||||
| 		s.listeners[eventType] = []OnEventListener{} | ||||
| @@ -112,13 +112,8 @@ func (s *DefaultSyncer) shouldProcessResponse(resp *RespSync, since string) bool | ||||
| 	for roomID, roomData := range resp.Rooms.Join { | ||||
| 		for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- { | ||||
| 			e := roomData.Timeline.Events[i] | ||||
| 			if e.Type == "m.room.member" && e.StateKey != nil && *e.StateKey == s.UserID { | ||||
| 				m := e.Content["membership"] | ||||
| 				mship, ok := m.(string) | ||||
| 				if !ok { | ||||
| 					continue | ||||
| 				} | ||||
| 				if mship == "join" { | ||||
| 			if e.Type == StateMember && e.GetStateKey() == s.UserID { | ||||
| 				if e.Content.Membership == "join" { | ||||
| 					_, ok := resp.Rooms.Join[roomID] | ||||
| 					if !ok { | ||||
| 						continue | ||||
|   | ||||
							
								
								
									
										21
									
								
								vendor/maunium.net/go/maulogger/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/maunium.net/go/maulogger/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2016 Tulir Asokan | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | ||||
| this software and associated documentation files (the "Software"), to deal in | ||||
| the Software without restriction, including without limitation the rights to | ||||
| use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||||
| of the Software, and to permit persons to whom the Software is furnished to do | ||||
| so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										6
									
								
								vendor/maunium.net/go/maulogger/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								vendor/maunium.net/go/maulogger/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| # maulogger | ||||
| A logger in Go. | ||||
|  | ||||
| Docs: [godoc.org/maunium.net/go/maulogger](https://godoc.org/maunium.net/go/maulogger) | ||||
|  | ||||
| Go get: `go get maunium.net/go/maulogger` | ||||
							
								
								
									
										219
									
								
								vendor/maunium.net/go/maulogger/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								vendor/maunium.net/go/maulogger/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | ||||
| package maulog | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Level is the severity level of a log entry. | ||||
| type Level struct { | ||||
| 	Name            string | ||||
| 	Severity, Color int | ||||
| } | ||||
|  | ||||
| // LogWriter writes to the log with an optional prefix | ||||
| type LogWriter struct { | ||||
| 	Level  Level | ||||
| 	Prefix string | ||||
| } | ||||
|  | ||||
| func (lw LogWriter) Write(p []byte) (n int, err error) { | ||||
| 	log(lw.Level, fmt.Sprint(lw.Prefix, string(p))) | ||||
| 	return len(p), nil | ||||
| } | ||||
|  | ||||
| // GetColor gets the ANSI escape color code for the log level. | ||||
| func (lvl Level) GetColor() []byte { | ||||
| 	if lvl.Color < 0 { | ||||
| 		return []byte("") | ||||
| 	} | ||||
| 	return []byte(fmt.Sprintf("\x1b[%dm", lvl.Color)) | ||||
| } | ||||
|  | ||||
| // GetReset gets the ANSI escape reset code. | ||||
| func (lvl Level) GetReset() []byte { | ||||
| 	if lvl.Color < 0 { | ||||
| 		return []byte("") | ||||
| 	} | ||||
| 	return []byte("\x1b[0m") | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// Debug is the level for debug messages. | ||||
| 	Debug = Level{Name: "DEBUG", Color: 36, Severity: 0} | ||||
| 	// Info is the level for basic log messages. | ||||
| 	Info = Level{Name: "INFO", Color: -1, Severity: 10} | ||||
| 	// Warn is the level saying that something went wrong, but the program will continue operating mostly normally. | ||||
| 	Warn = Level{Name: "WARN", Color: 33, Severity: 50} | ||||
| 	// Error is the level saying that something went wrong and the program may not operate as expected, but will still continue. | ||||
| 	Error = Level{Name: "ERROR", Color: 31, Severity: 100} | ||||
| 	// Fatal is the level saying that something went wrong and the program will not operate normally. | ||||
| 	Fatal = Level{Name: "FATAL", Color: 35, Severity: 9001} | ||||
| ) | ||||
|  | ||||
| // PrintLevel tells the first severity level at which messages should be printed to stdout | ||||
| var PrintLevel = 10 | ||||
|  | ||||
| // PrintDebug means PrintLevel = 0, kept for backwards compatibility | ||||
| var PrintDebug = false | ||||
|  | ||||
| // FileTimeformat is the time format used in log file names. | ||||
| var FileTimeformat = "2006-01-02" | ||||
|  | ||||
| // FileformatArgs is an undocumented integer. | ||||
| var FileformatArgs = 3 | ||||
|  | ||||
| // Fileformat is the format used for log file names. | ||||
| var Fileformat = func(now string, i int) string { return fmt.Sprintf("%[1]s-%02[2]d.log", now, i) } | ||||
|  | ||||
| // Timeformat is the time format used in logging. | ||||
| var Timeformat = "15:04:05 02.01.2006" | ||||
|  | ||||
| var writer *bufio.Writer | ||||
| var lines int | ||||
|  | ||||
| // InitWithWriter initializes MauLogger with the given writer. | ||||
| func InitWithWriter(w *bufio.Writer) { | ||||
| 	writer = w | ||||
| } | ||||
|  | ||||
| // Init initializes MauLogger. | ||||
| func Init() { | ||||
| 	// Find the next file name. | ||||
| 	now := time.Now().Format(FileTimeformat) | ||||
| 	i := 1 | ||||
| 	for ; ; i++ { | ||||
| 		if _, err := os.Stat(Fileformat(now, i)); os.IsNotExist(err) { | ||||
| 			break | ||||
| 		} | ||||
| 		if i == 99 { | ||||
| 			i = 1 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	// Open the file | ||||
| 	file, err := os.OpenFile(Fileformat(now, i), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0700) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	if file == nil { | ||||
| 		panic(os.ErrInvalid) | ||||
| 	} | ||||
| 	// Create a writer | ||||
| 	writer = bufio.NewWriter(file) | ||||
| } | ||||
|  | ||||
| // Debugf formats and logs a debug message. | ||||
| func Debugf(message string, args ...interface{}) { | ||||
| 	logln(Debug, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Printf formats and logs a string in the Info log level. | ||||
| func Printf(message string, args ...interface{}) { | ||||
| 	Infof(message, args...) | ||||
| } | ||||
|  | ||||
| // Infof formats and logs a string in the Info log level. | ||||
| func Infof(message string, args ...interface{}) { | ||||
| 	logln(Info, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Warnf formats and logs a string in the Warn log level. | ||||
| func Warnf(message string, args ...interface{}) { | ||||
| 	logln(Warn, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Errorf formats and logs a string in the Error log level. | ||||
| func Errorf(message string, args ...interface{}) { | ||||
| 	logln(Error, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Fatalf formats and logs a string in the Fatal log level. | ||||
| func Fatalf(message string, args ...interface{}) { | ||||
| 	logln(Fatal, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Logf formats and logs a message in the given log level. | ||||
| func Logf(level Level, message string, args ...interface{}) { | ||||
| 	logln(level, fmt.Sprintf(message, args...)) | ||||
| } | ||||
|  | ||||
| // Debugln logs a debug message. | ||||
| func Debugln(args ...interface{}) { | ||||
| 	log(Debug, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| // Println logs a string in the Info log level. | ||||
| func Println(args ...interface{}) { | ||||
| 	Infoln(args...) | ||||
| } | ||||
|  | ||||
| // Infoln logs a string in the Info log level. | ||||
| func Infoln(args ...interface{}) { | ||||
| 	log(Info, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| // Warnln logs a string in the Warn log level. | ||||
| func Warnln(args ...interface{}) { | ||||
| 	log(Warn, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| // Errorln logs a string in the Error log level. | ||||
| func Errorln(args ...interface{}) { | ||||
| 	log(Error, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| // Fatalln logs a string in the Fatal log level. | ||||
| func Fatalln(args ...interface{}) { | ||||
| 	log(Fatal, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| // Logln logs a message in the given log level. | ||||
| func Logln(level Level, args ...interface{}) { | ||||
| 	log(level, fmt.Sprintln(args...)) | ||||
| } | ||||
|  | ||||
| func logln(level Level, message string) { | ||||
| 	log(level, fmt.Sprintln(message)) | ||||
| } | ||||
|  | ||||
| func log(level Level, message string) { | ||||
| 	// Prefix the message with the timestamp and log level. | ||||
| 	msg := []byte(fmt.Sprintf("[%[1]s] [%[2]s] %[3]s", time.Now().Format(Timeformat), level.Name, message)) | ||||
|  | ||||
| 	if writer != nil { | ||||
| 		// Write it to the log file. | ||||
| 		_, err := writer.Write(msg) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 		lines++ | ||||
| 		// Flush the file if needed | ||||
| 		if lines == 5 { | ||||
| 			lines = 0 | ||||
| 			writer.Flush() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Print to stdout using correct color | ||||
| 	if level.Severity >= PrintLevel || PrintDebug { | ||||
| 		if level.Severity >= Error.Severity { | ||||
| 			os.Stderr.Write(level.GetColor()) | ||||
| 			os.Stderr.Write(msg) | ||||
| 			os.Stderr.Write(level.GetReset()) | ||||
| 		} else { | ||||
| 			os.Stdout.Write(level.GetColor()) | ||||
| 			os.Stdout.Write(msg) | ||||
| 			os.Stdout.Write(level.GetReset()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Shutdown cleans up the logger. | ||||
| func Shutdown() { | ||||
| 	if writer != nil { | ||||
| 		writer.Flush() | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user