From 95b8f8c9f208fa602816cb5329af71d55bafa02f Mon Sep 17 00:00:00 2001 From: negasus Date: Wed, 22 May 2024 17:14:55 +0300 Subject: [PATCH] add Marshal functions for struct with many types - ChatBoostSource - ChatBackground - ChatMember - MenuButton - MaybeInaccessibleMessage - ReactionType - MessageOrigin --- methods_test.go | 2 +- models/boost.go | 44 +++++++---- models/boost_test.go | 45 ++++++++++++ models/chat_background.go | 82 ++++++++++++++++----- models/chat_member.go | 149 ++++++++++++++++++++++---------------- models/menu_button.go | 51 +++++++++---- models/message.go | 12 +++ models/reaction.go | 18 ++--- models/reply.go | 69 +++++++++++------- 9 files changed, 326 insertions(+), 146 deletions(-) diff --git a/methods_test.go b/methods_test.go index 5a7bfd3..dfdf364 100644 --- a/methods_test.go +++ b/methods_test.go @@ -681,7 +681,7 @@ func TestBot_Methods(t *testing.T) { ChatID: 123, }) assertNoErr(t, err) - assertEqualInt(t, int(models.ChatMemberTypeAdministrator), int(resp.Type)) + assertEqualString(t, string(models.ChatMemberTypeAdministrator), string(resp.Type)) }) t.Run("SetChatStickerSet", func(t *testing.T) { diff --git a/models/boost.go b/models/boost.go index b8f2c84..bc608ba 100644 --- a/models/boost.go +++ b/models/boost.go @@ -48,7 +48,7 @@ type ChatBoostSource struct { func (cbs *ChatBoostSource) UnmarshalJSON(data []byte) error { v := struct { - Source string `json:"source"` + Source ChatBoostSourceType `json:"source"` }{} err := json.Unmarshal(data, &v) if err != nil { @@ -56,15 +56,15 @@ func (cbs *ChatBoostSource) UnmarshalJSON(data []byte) error { } switch v.Source { - case "premium": + case ChatBoostSourceTypePremium: cbs.Source = ChatBoostSourceTypePremium cbs.ChatBoostSourcePremium = &ChatBoostSourcePremium{} return json.Unmarshal(data, cbs.ChatBoostSourcePremium) - case "gift_code": + case ChatBoostSourceTypeGiftCode: cbs.Source = ChatBoostSourceTypeGiftCode cbs.ChatBoostSourceGiftCode = &ChatBoostSourceGiftCode{} return json.Unmarshal(data, cbs.ChatBoostSourceGiftCode) - case "giveaway": + case ChatBoostSourceTypeGiveaway: cbs.Source = ChatBoostSourceTypeGiveaway cbs.ChatBoostSourceGiveaway = &ChatBoostSourceGiveaway{} return json.Unmarshal(data, cbs.ChatBoostSourceGiveaway) @@ -73,29 +73,45 @@ func (cbs *ChatBoostSource) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported ChatBoostSource type") } +func (cbs *ChatBoostSource) MarshalJSON() ([]byte, error) { + switch cbs.Source { + case ChatBoostSourceTypePremium: + cbs.ChatBoostSourcePremium.Source = ChatBoostSourceTypePremium + return json.Marshal(cbs.ChatBoostSourcePremium) + case ChatBoostSourceTypeGiftCode: + cbs.ChatBoostSourceGiftCode.Source = ChatBoostSourceTypeGiftCode + return json.Marshal(cbs.ChatBoostSourceGiftCode) + case ChatBoostSourceTypeGiveaway: + cbs.ChatBoostSourceGiveaway.Source = ChatBoostSourceTypeGiveaway + return json.Marshal(cbs.ChatBoostSourceGiveaway) + } + + return nil, fmt.Errorf("unsupported ChatBoostSource type") +} + // ChatBoostSourceType https://core.telegram.org/bots/api#chatboostsource -type ChatBoostSourceType int +type ChatBoostSourceType string const ( - ChatBoostSourceTypePremium ChatBoostSourceType = iota - ChatBoostSourceTypeGiftCode - ChatBoostSourceTypeGiveaway + ChatBoostSourceTypePremium ChatBoostSourceType = "premium" + ChatBoostSourceTypeGiftCode ChatBoostSourceType = "gift_code" + ChatBoostSourceTypeGiveaway ChatBoostSourceType = "giveaway" ) // ChatBoostSourcePremium https://core.telegram.org/bots/api#chatboostsourcepremium type ChatBoostSourcePremium struct { - Source string `json:"source"` // always “premium” - User User `json:"user"` + Source ChatBoostSourceType `json:"source"` // always “premium” + User User `json:"user"` } // ChatBoostSourceGiftCode https://core.telegram.org/bots/api#chatboostsourcegiftcode type ChatBoostSourceGiftCode struct { - Source string `json:"source"` // always “gift_code” - User User `json:"user"` + Source ChatBoostSourceType `json:"source"` // always “gift_code” + User User `json:"user"` } // ChatBoostSourceGiveaway https://core.telegram.org/bots/api#chatboostsourcegiveaway type ChatBoostSourceGiveaway struct { - Source string `json:"source"` // always “giveaway” - User User `json:"user"` + Source ChatBoostSourceType `json:"source"` // always “giveaway” + User User `json:"user"` } diff --git a/models/boost_test.go b/models/boost_test.go index 3ae1304..f95cbca 100644 --- a/models/boost_test.go +++ b/models/boost_test.go @@ -70,3 +70,48 @@ func TestChatBoostSource_giveaway(t *testing.T) { t.Fatal("invalid user id") } } + +func TestChatBoostSource_premium_marshal_unmarshal(t *testing.T) { + src := `{"source":"premium","user":{"id":123}}` + + cbs := &ChatBoostSource{} + err := json.Unmarshal([]byte(src), cbs) + if err != nil { + t.Fatal(err) + } + + if cbs.Source != ChatBoostSourceTypePremium { + t.Fatal("invalid type") + } + + if cbs.ChatBoostSourcePremium == nil { + t.Fatal("invalid ChatBoostSourcePremium") + } + + if cbs.ChatBoostSourcePremium.User.ID != 123 { + t.Fatal("invalid user id") + } + + src2, err2 := json.Marshal(cbs) + if err2 != nil { + t.Fatal(err2) + } + + var cbs2 ChatBoostSource + err = json.Unmarshal(src2, &cbs2) + if err != nil { + t.Fatal(err) + } + + if cbs2.Source != ChatBoostSourceTypePremium { + t.Fatal("invalid type") + } + + if cbs2.ChatBoostSourcePremium == nil { + t.Fatal("invalid ChatBoostSourcePremium") + } + + if cbs2.ChatBoostSourcePremium.User.ID != 123 { + t.Fatal("invalid user id") + } +} diff --git a/models/chat_background.go b/models/chat_background.go index ad18ddf..5b082a1 100644 --- a/models/chat_background.go +++ b/models/chat_background.go @@ -26,26 +26,26 @@ type ChatBackground struct { func (cb *ChatBackground) UnmarshalJSON(data []byte) error { v := struct { - Type string `json:"type"` + Type BackgroundType `json:"type"` }{} if err := json.Unmarshal(data, &v); err != nil { return err } switch v.Type { - case "fill": + case ChatBackgroundTypeFill: cb.Type = ChatBackgroundTypeFill cb.Fill = &BackgroundTypeFill{} return json.Unmarshal(data, cb.Fill) - case "wallpaper": + case ChatBackgroundTypeWallpaper: cb.Type = ChatBackgroundTypeWallpaper cb.Wallpaper = &BackgroundTypeWallpaper{} return json.Unmarshal(data, cb.Wallpaper) - case "pattern": + case ChatBackgroundTypePattern: cb.Type = ChatBackgroundTypePattern cb.Pattern = &BackgroundTypePattern{} return json.Unmarshal(data, cb.Pattern) - case "chat_theme": + case ChatBackgroundTypeChatTheme: cb.Type = ChatBackgroundTypeChatTheme cb.Theme = &BackgroundTypeChatTheme{} return json.Unmarshal(data, cb.Theme) @@ -54,22 +54,44 @@ func (cb *ChatBackground) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported ChatBackground type") } +func (cb *ChatBackground) MarshalJSON() ([]byte, error) { + switch cb.Type { + case ChatBackgroundTypeFill: + cb.Fill.Type = ChatBackgroundTypeFill + return json.Marshal(cb.Fill) + case ChatBackgroundTypeWallpaper: + cb.Wallpaper.Type = ChatBackgroundTypeWallpaper + return json.Marshal(cb.Wallpaper) + case ChatBackgroundTypePattern: + cb.Pattern.Type = ChatBackgroundTypePattern + return json.Marshal(cb.Pattern) + case ChatBackgroundTypeChatTheme: + cb.Theme.Type = ChatBackgroundTypeChatTheme + return json.Marshal(cb.Theme) + } + + return nil, fmt.Errorf("unsupported ChatBackground type") +} + // BackgroundTypeFill https://core.telegram.org/bots/api#backgroundtypefill type BackgroundTypeFill struct { + Type BackgroundType `json:"type"` Fill BackgroundFill `json:"fill"` DarkThemeDimming int `json:"dark_theme_dimming"` } // BackgroundTypeWallpaper https://core.telegram.org/bots/api#backgroundtypewallpaper type BackgroundTypeWallpaper struct { - Document Document `json:"document"` - DarkThemeDimming int `json:"dark_theme_dimming"` - IsBlurred bool `json:"is_blurred,omitempty"` - IsMoving bool `json:"is_moving,omitempty"` + Type BackgroundType `json:"type"` + Document Document `json:"document"` + DarkThemeDimming int `json:"dark_theme_dimming"` + IsBlurred bool `json:"is_blurred,omitempty"` + IsMoving bool `json:"is_moving,omitempty"` } // BackgroundTypePattern https://core.telegram.org/bots/api#backgroundtypepattern type BackgroundTypePattern struct { + Type BackgroundType `json:"type"` Document Document `json:"document"` Fill BackgroundFill `json:"fill"` Intensity int `json:"intensity"` @@ -79,7 +101,8 @@ type BackgroundTypePattern struct { // BackgroundTypeChatTheme https://core.telegram.org/bots/api#backgroundtypechattheme type BackgroundTypeChatTheme struct { - ThemeName string `json:"theme_name"` + Type BackgroundType `json:"type"` + ThemeName string `json:"theme_name"` } type BackgroundFillType string @@ -91,7 +114,7 @@ const ( ) type BackgroundFill struct { - Type BackgroundFillType `json:"type"` + Type BackgroundFillType Solid *BackgroundFillSolid Gradient *BackgroundFillGradient FreeformGradient *BackgroundFillFreeformGradient @@ -99,22 +122,22 @@ type BackgroundFill struct { func (bf *BackgroundFill) UnmarshalJSON(data []byte) error { v := struct { - Type string `json:"type"` + Type BackgroundFillType `json:"type"` }{} if err := json.Unmarshal(data, &v); err != nil { return err } switch v.Type { - case "solid": + case BackgroundFillTypeSolid: bf.Type = BackgroundFillTypeSolid bf.Solid = &BackgroundFillSolid{} return json.Unmarshal(data, bf.Solid) - case "gradient": + case BackgroundFillTypeGradient: bf.Type = BackgroundFillTypeGradient bf.Gradient = &BackgroundFillGradient{} return json.Unmarshal(data, bf.Gradient) - case "freeform_gradient": + case BackgroundFillTypeFreeformGradient: bf.Type = BackgroundFillTypeFreeformGradient bf.FreeformGradient = &BackgroundFillFreeformGradient{} return json.Unmarshal(data, bf.FreeformGradient) @@ -123,19 +146,38 @@ func (bf *BackgroundFill) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported BackgroundFill type") } +func (bf *BackgroundFill) MarshalJSON() ([]byte, error) { + switch bf.Type { + case BackgroundFillTypeSolid: + bf.Solid.Type = BackgroundFillTypeSolid + return json.Marshal(bf.Solid) + case BackgroundFillTypeGradient: + bf.Gradient.Type = BackgroundFillTypeGradient + return json.Marshal(bf.Gradient) + case BackgroundFillTypeFreeformGradient: + bf.FreeformGradient.Type = BackgroundFillTypeFreeformGradient + return json.Marshal(bf.FreeformGradient) + } + + return nil, fmt.Errorf("unsupported BackgroundFill type") +} + // BackgroundFillSolid https://core.telegram.org/bots/api#backgroundfillsolid type BackgroundFillSolid struct { - Color int `json:"color"` + Type BackgroundFillType `json:"type"` + Color int `json:"color"` } // BackgroundFillGradient https://core.telegram.org/bots/api#backgroundfillgradient type BackgroundFillGradient struct { - TopColor int `json:"top_color"` - BottomColor int `json:"bottom_color"` - RotationAngle int `json:"rotation_angle"` + Type BackgroundFillType `json:"type"` + TopColor int `json:"top_color"` + BottomColor int `json:"bottom_color"` + RotationAngle int `json:"rotation_angle"` } // BackgroundFillFreeformGradient https://core.telegram.org/bots/api#backgroundfillfreeformgradient type BackgroundFillFreeformGradient struct { - Colors []int `json:"colors"` + Type BackgroundFillType `json:"type"` + Colors []int `json:"colors"` } diff --git a/models/chat_member.go b/models/chat_member.go index d08671a..e3cb60a 100644 --- a/models/chat_member.go +++ b/models/chat_member.go @@ -17,15 +17,15 @@ type ChatMemberUpdated struct { ViaChatFolderInviteLink bool `json:"via_chat_folder_invite_link,omitempty"` } -type ChatMemberType int +type ChatMemberType string const ( - ChatMemberTypeOwner ChatMemberType = iota - ChatMemberTypeAdministrator - ChatMemberTypeMember - ChatMemberTypeRestricted - ChatMemberTypeLeft - ChatMemberTypeBanned + ChatMemberTypeOwner ChatMemberType = "creator" + ChatMemberTypeAdministrator ChatMemberType = "administrator" + ChatMemberTypeMember ChatMemberType = "member" + ChatMemberTypeRestricted ChatMemberType = "restricted" + ChatMemberTypeLeft ChatMemberType = "left" + ChatMemberTypeBanned ChatMemberType = "kicked" ) // ChatMember https://core.telegram.org/bots/api#chatmember @@ -42,34 +42,34 @@ type ChatMember struct { func (c *ChatMember) UnmarshalJSON(data []byte) error { v := struct { - Status string `json:"status"` + Status ChatMemberType `json:"status"` }{} if err := json.Unmarshal(data, &v); err != nil { return err } switch v.Status { - case "creator": + case ChatMemberTypeOwner: c.Type = ChatMemberTypeOwner c.Owner = &ChatMemberOwner{} return json.Unmarshal(data, c.Owner) - case "administrator": + case ChatMemberTypeAdministrator: c.Type = ChatMemberTypeAdministrator c.Administrator = &ChatMemberAdministrator{} return json.Unmarshal(data, c.Administrator) - case "member": + case ChatMemberTypeMember: c.Type = ChatMemberTypeMember c.Member = &ChatMemberMember{} return json.Unmarshal(data, c.Member) - case "restricted": + case ChatMemberTypeRestricted: c.Type = ChatMemberTypeRestricted c.Restricted = &ChatMemberRestricted{} return json.Unmarshal(data, c.Restricted) - case "left": + case ChatMemberTypeLeft: c.Type = ChatMemberTypeLeft c.Left = &ChatMemberLeft{} return json.Unmarshal(data, c.Left) - case "kicked": + case ChatMemberTypeBanned: c.Type = ChatMemberTypeBanned c.Banned = &ChatMemberBanned{} return json.Unmarshal(data, c.Banned) @@ -78,74 +78,99 @@ func (c *ChatMember) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported ChatMember type") } +func (c *ChatMember) MarshalJSON() ([]byte, error) { + switch c.Type { + case ChatMemberTypeOwner: + c.Owner.Status = ChatMemberTypeOwner + return json.Marshal(c.Owner) + case ChatMemberTypeAdministrator: + c.Administrator.Status = ChatMemberTypeAdministrator + return json.Marshal(c.Administrator) + case ChatMemberTypeMember: + c.Member.Status = ChatMemberTypeMember + return json.Marshal(c.Member) + case ChatMemberTypeRestricted: + c.Restricted.Status = ChatMemberTypeRestricted + return json.Marshal(c.Restricted) + case ChatMemberTypeLeft: + c.Left.Status = ChatMemberTypeLeft + return json.Marshal(c.Left) + case ChatMemberTypeBanned: + c.Banned.Status = ChatMemberTypeBanned + return json.Marshal(c.Banned) + } + + return nil, fmt.Errorf("unsupported ChatMember type") +} + // ChatMemberOwner https://core.telegram.org/bots/api#chatmemberowner type ChatMemberOwner struct { - Status string `json:"status"` // The member's status in the chat, always “creator” - User *User `json:"user"` - IsAnonymous bool `json:"is_anonymous"` - CustomTitle string `json:"custom_title,omitempty"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “creator” + User *User `json:"user"` + IsAnonymous bool `json:"is_anonymous"` + CustomTitle string `json:"custom_title,omitempty"` } // ChatMemberAdministrator https://core.telegram.org/bots/api#chatmemberadministrator type ChatMemberAdministrator struct { - Status string `json:"status"` // The member's status in the chat, always “administrator” - User User `json:"user"` - CanBeEdited bool `json:"can_be_edited"` - IsAnonymous bool `json:"is_anonymous"` - CanManageChat bool `json:"can_manage_chat"` - CanDeleteMessages bool `json:"can_delete_messages"` - CanManageVideoChats bool `json:"can_manage_video_chats"` - CanRestrictMembers bool `json:"can_restrict_members"` - CanPromoteMembers bool `json:"can_promote_members"` - CanChangeInfo bool `json:"can_change_info"` - CanInviteUsers bool `json:"can_invite_users"` - CanPostMessages bool `json:"can_post_messages,omitempty"` - CanEditMessages bool `json:"can_edit_messages,omitempty"` - CanPinMessages bool `json:"can_pin_messages,omitempty"` - CanPostStories bool `json:"can_post_stories,omitempty"` - CanEditStories bool `json:"can_edit_stories,omitempty"` - CanDeleteStories bool `json:"can_delete_stories,omitempty"` - CanManageTopics bool `json:"can_manage_topics,omitempty"` - CustomTitle string `json:"custom_title,omitempty"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “administrator” + User User `json:"user"` + CanBeEdited bool `json:"can_be_edited"` + IsAnonymous bool `json:"is_anonymous"` + CanManageChat bool `json:"can_manage_chat"` + CanDeleteMessages bool `json:"can_delete_messages"` + CanManageVideoChats bool `json:"can_manage_video_chats"` + CanRestrictMembers bool `json:"can_restrict_members"` + CanPromoteMembers bool `json:"can_promote_members"` + CanChangeInfo bool `json:"can_change_info"` + CanInviteUsers bool `json:"can_invite_users"` + CanPostMessages bool `json:"can_post_messages,omitempty"` + CanEditMessages bool `json:"can_edit_messages,omitempty"` + CanPinMessages bool `json:"can_pin_messages,omitempty"` + CanPostStories bool `json:"can_post_stories,omitempty"` + CanEditStories bool `json:"can_edit_stories,omitempty"` + CanDeleteStories bool `json:"can_delete_stories,omitempty"` + CanManageTopics bool `json:"can_manage_topics,omitempty"` + CustomTitle string `json:"custom_title,omitempty"` } // ChatMemberMember https://core.telegram.org/bots/api#chatmembermember type ChatMemberMember struct { - Status string `json:"status"` // The member's status in the chat, always “member” - User *User `json:"user"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “member” + User *User `json:"user"` } // ChatMemberRestricted https://core.telegram.org/bots/api#chatmemberrestricted type ChatMemberRestricted struct { - Status string `json:"status"` // The member's status in the chat, always “restricted” - User *User `json:"user"` - IsMember bool `json:"is_member"` - CanSendMessages bool `json:"can_send_messages"` - CanSendAudios bool `json:"can_send_audios"` - CanSendDocuments bool `json:"can_send_documents"` - CanSendPhotos bool `json:"can_send_photos"` - CanSendVideos bool `json:"can_send_videos"` - CanSendVideoNotes bool `json:"can_send_video_notes"` - CanSendVoiceNotes bool `json:"can_send_voice_notes"` - CanSendPolls bool `json:"can_send_polls"` - CanSendOtherMessages bool `json:"can_send_other_messages"` - CanAddWebPagePreviews bool `json:"can_add_web_page_previews"` - CanChangeInfo bool `json:"can_change_info"` - CanInviteUsers bool `json:"can_invite_users"` - CanPinMessages bool `json:"can_pin_messages"` - CanManageTopics bool `json:"can_manage_topics,omitempty"` - UntilDate int `json:"until_date"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “restricted” + User *User `json:"user"` + IsMember bool `json:"is_member"` + CanSendMessages bool `json:"can_send_messages"` + CanSendAudios bool `json:"can_send_audios"` + CanSendDocuments bool `json:"can_send_documents"` + CanSendPhotos bool `json:"can_send_photos"` + CanSendVideos bool `json:"can_send_videos"` + CanSendVideoNotes bool `json:"can_send_video_notes"` + CanSendVoiceNotes bool `json:"can_send_voice_notes"` + CanSendPolls bool `json:"can_send_polls"` + CanSendOtherMessages bool `json:"can_send_other_messages"` + CanAddWebPagePreviews bool `json:"can_add_web_page_previews"` + CanChangeInfo bool `json:"can_change_info"` + CanInviteUsers bool `json:"can_invite_users"` + CanPinMessages bool `json:"can_pin_messages"` + CanManageTopics bool `json:"can_manage_topics,omitempty"` + UntilDate int `json:"until_date"` } // ChatMemberLeft https://core.telegram.org/bots/api#chatmemberleft type ChatMemberLeft struct { - Status string `json:"status"` // The member's status in the chat, always “left” - User *User `json:"user"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “left” + User *User `json:"user"` } // ChatMemberBanned https://core.telegram.org/bots/api#chatmemberbanned type ChatMemberBanned struct { - Status string `json:"status"` // The member's status in the chat, always “kicked” - User *User `json:"user"` - UntilDate int `json:"until_date"` + Status ChatMemberType `json:"status"` // The member's status in the chat, always “kicked” + User *User `json:"user"` + UntilDate int `json:"until_date"` } diff --git a/models/menu_button.go b/models/menu_button.go index e0b1a3c..1cb2c44 100644 --- a/models/menu_button.go +++ b/models/menu_button.go @@ -1,17 +1,16 @@ package models import ( - "bytes" "encoding/json" "fmt" ) -type MenuButtonType int +type MenuButtonType string const ( - MenuButtonTypeCommands MenuButtonType = iota - MenuButtonTypeWebApp - MenuButtonTypeDefault + MenuButtonTypeCommands MenuButtonType = "commands" + MenuButtonTypeWebApp MenuButtonType = "web_app" + MenuButtonTypeDefault MenuButtonType = "default" ) type InputMenuButton interface { @@ -28,17 +27,23 @@ type MenuButton struct { } func (c *MenuButton) UnmarshalJSON(data []byte) error { - if bytes.Contains(data, []byte(`"type":"commands"`)) { + v := struct { + Type MenuButtonType `json:"type"` + }{} + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + switch v.Type { + case MenuButtonTypeCommands: c.Type = MenuButtonTypeCommands c.Commands = &MenuButtonCommands{} return json.Unmarshal(data, c.Commands) - } - if bytes.Contains(data, []byte(`"type":"web_app"`)) { + case MenuButtonTypeWebApp: c.Type = MenuButtonTypeWebApp c.WebApp = &MenuButtonWebApp{} return json.Unmarshal(data, c.WebApp) - } - if bytes.Contains(data, []byte(`"type":"default"`)) { + case MenuButtonTypeDefault: c.Type = MenuButtonTypeDefault c.Default = &MenuButtonDefault{} return json.Unmarshal(data, c.Default) @@ -47,25 +52,41 @@ func (c *MenuButton) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported MenuButton type") } +func (c *MenuButton) MarshalJSON() ([]byte, error) { + switch c.Type { + case MenuButtonTypeCommands: + c.Commands.Type = MenuButtonTypeCommands + return json.Marshal(c.Commands) + case MenuButtonTypeWebApp: + c.WebApp.Type = MenuButtonTypeWebApp + return json.Marshal(c.WebApp) + case MenuButtonTypeDefault: + c.Default.Type = MenuButtonTypeDefault + return json.Marshal(c.Default) + } + + return nil, fmt.Errorf("unsupported MenuButton type") +} + // MenuButtonCommands https://core.telegram.org/bots/api#menubuttoncommands type MenuButtonCommands struct { - Type string `json:"type" rules:"required,equals:commands"` + Type MenuButtonType `json:"type" rules:"required,equals:commands"` } func (MenuButtonCommands) menuButtonTag() {} // MenuButtonWebApp https://core.telegram.org/bots/api#menubuttonwebapp type MenuButtonWebApp struct { - Type string `json:"type" rules:"required,equals:web_app"` - Text string `json:"text" rules:"required"` - WebApp WebAppInfo `json:"web_app" rules:"required"` + Type MenuButtonType `json:"type" rules:"required,equals:web_app"` + Text string `json:"text" rules:"required"` + WebApp WebAppInfo `json:"web_app" rules:"required"` } func (MenuButtonWebApp) menuButtonTag() {} // MenuButtonDefault https://core.telegram.org/bots/api#menubuttondefault type MenuButtonDefault struct { - Type string `json:"type" rules:"required,equals:default"` + Type MenuButtonType `json:"type" rules:"required,equals:default"` } func (MenuButtonDefault) menuButtonTag() {} diff --git a/models/message.go b/models/message.go index 6eecd5b..317d146 100644 --- a/models/message.go +++ b/models/message.go @@ -2,6 +2,7 @@ package models import ( "encoding/json" + "fmt" ) // MaybeInaccessibleMessageType https://core.telegram.org/bots/api#maybeinaccessiblemessage @@ -40,6 +41,17 @@ func (mim *MaybeInaccessibleMessage) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, mim.Message) } +func (mim *MaybeInaccessibleMessage) MarshalJSON() ([]byte, error) { + switch mim.Type { + case MaybeInaccessibleMessageTypeMessage: + return json.Marshal(mim.Message) + case MaybeInaccessibleMessageTypeInaccessibleMessage: + return json.Marshal(mim.InaccessibleMessage) + } + + return nil, fmt.Errorf("unsupported MaybeInaccessibleMessage type") +} + // InaccessibleMessage https://core.telegram.org/bots/api#inaccessiblemessage type InaccessibleMessage struct { Chat Chat `json:"chat"` diff --git a/models/reaction.go b/models/reaction.go index fa5d4ac..f0973a6 100644 --- a/models/reaction.go +++ b/models/reaction.go @@ -6,11 +6,11 @@ import ( ) // ReactionTypeType https://core.telegram.org/bots/api#reactiontype -type ReactionTypeType int +type ReactionTypeType string const ( - ReactionTypeTypeEmoji ReactionTypeType = iota - ReactionTypeTypeCustomEmoji + ReactionTypeTypeEmoji ReactionTypeType = "emoji" + ReactionTypeTypeCustomEmoji ReactionTypeType = "custom_emoji" ) // ReactionType https://core.telegram.org/bots/api#reactiontype @@ -24,10 +24,10 @@ type ReactionType struct { func (rt *ReactionType) MarshalJSON() ([]byte, error) { switch rt.Type { case ReactionTypeTypeEmoji: - rt.ReactionTypeEmoji.Type = "emoji" + rt.ReactionTypeEmoji.Type = ReactionTypeTypeEmoji return json.Marshal(rt.ReactionTypeEmoji) case ReactionTypeTypeCustomEmoji: - rt.ReactionTypeCustomEmoji.Type = "custom_emoji" + rt.ReactionTypeCustomEmoji.Type = ReactionTypeTypeCustomEmoji return json.Marshal(rt.ReactionTypeCustomEmoji) } @@ -59,14 +59,14 @@ func (rt *ReactionType) UnmarshalJSON(data []byte) error { // ReactionTypeEmoji https://core.telegram.org/bots/api#reactiontypeemoji type ReactionTypeEmoji struct { - Type string `json:"type"` - Emoji string `json:"emoji"` + Type ReactionTypeType `json:"type"` + Emoji string `json:"emoji"` } // ReactionTypeCustomEmoji https://core.telegram.org/bots/api#reactiontypecustomemoji type ReactionTypeCustomEmoji struct { - Type string `json:"type"` - CustomEmojiID string `json:"custom_emoji_id"` + Type ReactionTypeType `json:"type"` + CustomEmojiID string `json:"custom_emoji_id"` } // MessageReactionUpdated https://core.telegram.org/bots/api#messagereactionupdated diff --git a/models/reply.go b/models/reply.go index 7983022..718c901 100644 --- a/models/reply.go +++ b/models/reply.go @@ -52,13 +52,13 @@ type ReplyParameters struct { } // MessageOriginType https://core.telegram.org/bots/api#messageorigin -type MessageOriginType int +type MessageOriginType string const ( - MessageOriginTypeUser MessageOriginType = iota - MessageOriginTypeHiddenUser - MessageOriginTypeChat - MessageOriginTypeChannel + MessageOriginTypeUser MessageOriginType = "user" + MessageOriginTypeHiddenUser MessageOriginType = "hidden_user" + MessageOriginTypeChat MessageOriginType = "chat" + MessageOriginTypeChannel MessageOriginType = "channel" ) // MessageOrigin https://core.telegram.org/bots/api#messageorigin @@ -73,26 +73,26 @@ type MessageOrigin struct { func (mo *MessageOrigin) UnmarshalJSON(data []byte) error { v := struct { - Type string `json:"type"` + Type MessageOriginType `json:"type"` }{} if err := json.Unmarshal(data, &v); err != nil { return err } switch v.Type { - case "user": + case MessageOriginTypeUser: mo.Type = MessageOriginTypeUser mo.MessageOriginUser = &MessageOriginUser{} return json.Unmarshal(data, mo.MessageOriginUser) - case "hidden_user": + case MessageOriginTypeHiddenUser: mo.Type = MessageOriginTypeHiddenUser mo.MessageOriginHiddenUser = &MessageOriginHiddenUser{} return json.Unmarshal(data, mo.MessageOriginHiddenUser) - case "chat": + case MessageOriginTypeChat: mo.Type = MessageOriginTypeChat mo.MessageOriginChat = &MessageOriginChat{} return json.Unmarshal(data, mo.MessageOriginChat) - case "channel": + case MessageOriginTypeChannel: mo.Type = MessageOriginTypeChannel mo.MessageOriginChannel = &MessageOriginChannel{} return json.Unmarshal(data, mo.MessageOriginChannel) @@ -101,33 +101,52 @@ func (mo *MessageOrigin) UnmarshalJSON(data []byte) error { return fmt.Errorf("unsupported MessageOrigin type") } +func (mo *MessageOrigin) MarshalJSON() ([]byte, error) { + switch mo.Type { + case MessageOriginTypeUser: + mo.MessageOriginUser.Type = MessageOriginTypeUser + return json.Marshal(mo.MessageOriginUser) + case MessageOriginTypeHiddenUser: + mo.MessageOriginHiddenUser.Type = MessageOriginTypeHiddenUser + return json.Marshal(mo.MessageOriginHiddenUser) + case MessageOriginTypeChat: + mo.MessageOriginChat.Type = MessageOriginTypeChat + return json.Marshal(mo.MessageOriginChat) + case MessageOriginTypeChannel: + mo.MessageOriginChannel.Type = MessageOriginTypeChannel + return json.Marshal(mo.MessageOriginChannel) + } + + return nil, fmt.Errorf("unsupported MessageOrigin type") +} + // MessageOriginUser https://core.telegram.org/bots/api#messageoriginuser type MessageOriginUser struct { - Type string `json:"type"` // always “user” - Date int `json:"date"` - SenderUser User `json:"sender_user"` + Type MessageOriginType `json:"type"` // always “user” + Date int `json:"date"` + SenderUser User `json:"sender_user"` } // MessageOriginHiddenUser https://core.telegram.org/bots/api#messageoriginhiddenuser type MessageOriginHiddenUser struct { - Type string `json:"type"` // always “hidden_user” - Date int `json:"date"` - SenderUserName string `json:"sender_user_name"` + Type MessageOriginType `json:"type"` // always “hidden_user” + Date int `json:"date"` + SenderUserName string `json:"sender_user_name"` } // MessageOriginChat https://core.telegram.org/bots/api#messageoriginchat type MessageOriginChat struct { - Type string `json:"type"` // always “chat” - Date int `json:"date"` - SenderChat Chat `json:"sender_chat"` - AuthorSignature *string `json:"author_signature,omitempty"` + Type MessageOriginType `json:"type"` // always “chat” + Date int `json:"date"` + SenderChat Chat `json:"sender_chat"` + AuthorSignature *string `json:"author_signature,omitempty"` } // MessageOriginChannel https://core.telegram.org/bots/api#messageoriginchannel type MessageOriginChannel struct { - Type string `json:"type"` // always “channel” - Date int `json:"date"` - Chat Chat `json:"chat"` - MessageID int `json:"message_id"` - AuthorSignature *string `json:"author_signature,omitempty"` + Type MessageOriginType `json:"type"` // always “channel” + Date int `json:"date"` + Chat Chat `json:"chat"` + MessageID int `json:"message_id"` + AuthorSignature *string `json:"author_signature,omitempty"` }