Skip to content

Commit

Permalink
Replace IQR*.MarshalJSON with InlineQueryResultBase, fixes tucnak#75.
Browse files Browse the repository at this point in the history
This commit gets rid of multiple redundant copies of MarhsalJSON()
method present for all existing IQR. It does so by introducing a
new struct called InlineQueryResultBase, which takes care of new
Type (for JSON) and existing duplicated ID field.

InlineQueryResults is a new helper wrapper for []IQR slices. It
implements MarshalJSON, which makes sure IQR.ID and IQR.Type are
set properly (by computing a hash and infering IQR type).
  • Loading branch information
Ian Byrd committed Nov 10, 2016
1 parent fedfe0d commit a6c1dce
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 366 deletions.
67 changes: 57 additions & 10 deletions inline.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package telebot

import (
"encoding/json"
"fmt"
"hash/fnv"
"strconv"

Expand Down Expand Up @@ -41,7 +43,7 @@ type QueryResponse struct {
QueryID string `json:"inline_query_id"`

// The results for the inline query.
Results []InlineQueryResult `json:"results"`
Results InlineQueryResults `json:"results"`

// (Optional) The maximum amount of time in seconds that the result
// of the inline query may be cached on the server.
Expand Down Expand Up @@ -70,18 +72,63 @@ type QueryResponse struct {

// InlineQueryResult represents one result of an inline query.
type InlineQueryResult interface {
MarshalJSON() ([]byte, error)
id() (string, error)
GetID() string
SetID(string)
}

// InlineQueryResults is a slice wrapper for convenient marshalling.
type InlineQueryResults []InlineQueryResult

func (results *InlineQueryResults) MarshalJSON() ([]byte, error) {
for i, result := range *results {
if result.GetID() == "" {
hash, err := hashstructure.Hash(result, inlineQueryHashOptions)
if err != nil {
return nil, fmt.Errorf("telebot: can't hash IQR #%d: %s",
i, err)
}

result.SetID(strconv.FormatUint(hash, 16))
}

if err := infereIQR(result); err != nil {
return nil, fmt.Errorf("telebot: can't infere type of IQR #%d: %s",
i, err)
}
}

return json.Marshal([]InlineQueryResult(*results))
}

// hashInlineQueryResult calculates the 64-bit FNV-1 hash of an
// inline query result.
func hashInlineQueryResult(result InlineQueryResult) (string, error) {
hash, err := hashstructure.Hash(result, inlineQueryHashOptions)
if err != nil {
return "", err
func infereIQR(result InlineQueryResult) error {
switch r := result.(type) {
case *InlineQueryResultArticle:
r.Type = "article"
case *InlineQueryResultAudio:
r.Type = "audio"
case *InlineQueryResultContact:
r.Type = "contact"
case *InlineQueryResultDocument:
r.Type = "document"
case *InlineQueryResultGif:
r.Type = "gif"
case *InlineQueryResultLocation:
r.Type = "location"
case *InlineQueryResultMpeg4Gif:
r.Type = "mpeg4_gif"
case *InlineQueryResultPhoto:
r.Type = "photo"
case *InlineQueryResultVenue:
r.Type = "venue"
case *InlineQueryResultVideo:
r.Type = "video"
case *InlineQueryResultVoice:
r.Type = "voice"
default:
return fmt.Errorf("%T is not an IQR", result)
}
return strconv.FormatUint(hash, 16), nil

return nil
}

// Result is a deprecated type, superseded by InlineQueryResult.
Expand Down
Loading

0 comments on commit a6c1dce

Please sign in to comment.