<commit_before>package tgbot

import "encoding/json"

// Update represents an incoming update
type Update struct {
	UpdateID           int                 `json:"update_id"`
	Message            *Message            `json:"message"`
	EditedMessage      *Message            `json:"edited_message"`
	ChannelPost        *Message            `json:"channel_post"`
	EditedChannelPost  *Message            `json:"edited_channel_post"`
	InlineQuery        *InlineQuery        `json:"inline_query"`
	ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
	CallbackQuery      *CallbackQuery      `json:"callback_query"`
	ShippingQuery      *ShippingQuery      `json:"shipping_query"`
	PreCheckoutQuery   *PreCheckoutQuery   `json:"pre_checkout_query"`
}

// WebhookInfo contains information about the current status of a webhook
type WebhookInfo struct {
	URL                  string   `json:"url"`
	HasCustomCertificate bool     `json:"has_custom_certificate"`
	PendingUpdateCount   int      `json:"pending_update_count"`
	LastErrorDate        int      `json:"last_error_date"`
	LastErrorMessage     string   `json:"last_error_message"`
	MaxConnections       int      `json:"max_connections"`
	AllowedUpdates       []string `json:"allowed_updates"`
}

// Message represents a message
type Message struct {
	MessageID             int                `json:"message_id"`
	From                  *User              `json:"from"`
	Date                  int                `json:"date"`
	Chat                  *Chat              `json:"chat"`
	ForwardFrom           *User              `json:"forward_from"`
	ForwardFromChat       *Chat              `json:"forward_from_chat"`
	ForwardFromMessageID  int                `json:"forward_from_message_id"`
	ForwardSignature      string             `json:"forward_signature"`
	ForwardDate           int                `json:"forward_date"`
	ReplyToMessage        *Message           `json:"reply_to_message"`
	EditDate              int                `json:"edit_date"`
	AuthorSignature       string             `json:"author_signature"`
	Text                  string             `json:"text"`
	Entities              []*MessageEntity   `json:"entities"`
	Audio                 *Audio             `json:"audio"`
	Document              *Document          `json:"document"`
	Game                  *Game              `json:"game"`
	Photo                 []*PhotoSize       `json:"photo"`
	Sticker               *Sticker           `json:"sticker"`
	Video                 *Video             `json:"video"`
	Voice                 *Voice             `json:"voice"`
	VideoNote             *VideoNote         `json:"video_note"`
	NewChatMembers        []*User            `json:"new_chat_members"`
	Caption               string             `json:"caption"`
	Contact               *Contact           `json:"contact"`
	Location              *Location          `json:"location"`
	Venue                 *Venue             `json:"venue"`
	NewChatMember         *User              `json:"new_chat_member"`
	LeftChatMember        *User              `json:"left_chat_member"`
	NewChatTitle          string             `json:"new_chat_title"`
	NewChatPhoto          []*PhotoSize       `json:"new_chat_photo"`
	DeleteChatPhoto       bool               `json:"delete_chat_photo"`
	GroupChatCreated      bool               `json:"group_chat_created"`
	SupergroupChatCreated bool               `json:"supergroup_chat_created"`
	ChannelChatCreated    bool               `json:"channel_chat_created"`
	MigrateToChatID       int64              `json:"migrate_to_chat_id"`
	MigrateFromChatID     int64              `json:"migrate_from_chat_id"`
	PinnedMessage         *Message           `json:"pinned_message"`
	SuccessfulPayment     *SuccessfulPayment `json:"successful_payment"`
}

// User represents a user
type User struct {
	ID           int    `json:"id"`
	IsBot        bool   `json:"is_bot"`
	FirstName    string `json:"first_name"`
	LastName     string `json:"last_name"`
	Username     string `json:"username"`
	LanguageCode string `json:"language_code"`
}

// Chat represents a chat
type Chat struct {
	ID                          int64      `json:"id"`
	Type                        string     `json:"type"`
	Title                       string     `json:"title"`
	Username                    string     `json:"username"`
	FirstName                   string     `json:"first_name"`
	LastName                    string     `json:"last_name"`
	AllMembersAreAdministrators bool       `json:"all_members_are_administrators"`
	Photo                       *ChatPhoto `json:"photo"`
	Description                 string     `json:"description"`
	InviteLink                  string     `json:"invite_link"`
	PinnedMessage               *Message   `json:"pinned_message"`
}

// ChatPhoto represents a chat photo
type ChatPhoto struct {
	SmallFileID string `json:"small_file_id"`
	BigFileID   string `json:"big_file_id"`
}

// MessageEntity represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
type MessageEntity struct {
	Type   string `json:"type"`
	Offset int    `json:"offset"`
	Length int    `json:"length"`
	URL    string `json:"url"`
	User   *User  `json:"user"`
}

// Audio represents an audio file to be treated as music by the Telegram clients
type Audio struct {
	FileID    string `json:"file_id"`
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
	FileSize  int    `json:"file_size"`
}

// Document represents a general file (as opposed to photos, voice messages and audio files)
type Document struct {
	FileID   string     `json:"file_id"`
	Thumb    *PhotoSize `json:"thumb"`
	FileName string     `json:"file_name"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// PhotoSize represents one size of a photo or a file / sticker thumbnail
type PhotoSize struct {
	FileID   string `json:"file_id"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
	FileSize int    `json:"file_size"`
}

// Game represents a game.
// Use BotFather to create and edit games, their short names will act as unique identifiers.
type Game struct {
	Title        string           `json:"title"`
	Description  string           `json:"description"`
	Photo        []*PhotoSize     `json:"photo"`
	Text         string           `json:"text"`
	TextEntities []*MessageEntity `json:"text_entities"`
	Animation    *Animation       `json:"animation"`
}

// Animation represents an animation file to be displayed in the message containing a game
type Animation struct {
	FileID   string     `json:"file_id"`
	Thumb    *PhotoSize `json:"thumb"`
	FileName string     `json:"file_name"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// Sticker represents a sticker
type Sticker struct {
	FileID       string        `json:"file_id"`
	Width        int           `json:"width"`
	Height       int           `json:"height"`
	Thumb        *PhotoSize    `json:"thumb"`
	Emoji        string        `json:"emoji"`
	SetName      string        `json:"set_name"`
	MaskPosition *MaskPosition `json:"mask_position"`
	FileSize     int           `json:"file_size"`
}

// StickerSet represents a sticker set
type StickerSet struct {
	Name          string     `json:"name"`
	Title         string     `json:"title"`
	ContainsMasks bool       `json:"contains_masks"`
	Stickers      []*Sticker `json:"stickers"`
}

// MaskPosition describes the position on faces where a mask should be placed by default.
// TODO: Turn it into a method.
type MaskPosition struct {
	Point  string  `json:"point"`
	XShift float32 `json:"x_shift"`
	YShift float32 `json:"y_shift"`
	Scale  float32 `json:"scale"`
}

// Video represents a video file
type Video struct {
	FileID   string     `json:"file_id"`
	Width    int        `json:"width"`
	Height   int        `json:"height"`
	Duration int        `json:"duration"`
	Thumb    *PhotoSize `json:"thumb"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// Voice represents a voice note
type Voice struct {
	FileID   string `json:"file_id"`
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
	FileSize int    `json:"file_size"`
}

// VideoNote represents a video message
type VideoNote struct {
	FileID   string     `json:"file_id"`
	Length   int        `json:"length"`
	Duration int        `json:"duration"`
	Thumb    *PhotoSize `json:"thumb"`
	FileSize int        `json:"file_size"`
}

// Contact represents a phone contact
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      int    `json:"user_id"`
}

// Location represents a point on the map
type Location struct {
	Longitude float32 `json:"longitude"`
	Latitude  float32 `json:"latitude"`
}

// Venue represents a venue
type Venue struct {
	Location     *Location `json:"location"`
	Title        string    `json:"title"`
	Address      string    `json:"address"`
	FoursquareID string    `json:"foursquare_id"`
}

// Invoice contains basic information about a invoice
type Invoice struct {
	Title          string `json:"title"`
	Description    string `json:"description"`
	StartParameter string `json:"start_parameter"`
	Currency       string `json:"currency"`
	TotalAmount    int    `json:"total_amount"`
}

// SuccessfulPayment contains basic information about a successful payment
type SuccessfulPayment struct {
	Currency                string     `json:"currency"`
	TotalAmount             int        `json:"total_amount"`
	InvoicePayload          string     `json:"invoice_payload"`
	ShippingOptionID        string     `json:"shipping_option_id"`
	OrderInfo               *OrderInfo `json:"order_info"`
	TelegramPaymentChargeID string     `json:"telegram_payment_charge_id"`
	ProviderPaymentChargeID string     `json:"provider_payment_charge_id"`
}

// OrderInfo represents information about an order
type OrderInfo struct {
	Name            string           `json:"name"`
	PhoneNumber     string           `json:"phone_number"`
	Email           string           `json:"email"`
	ShippingAddress *ShippingAddress `json:"shipping_address"`
}

// ShippingAddress represents a shipping address
type ShippingAddress struct {
	CountryCode string `json:"country_code"`
	State       string `json:"state"`
	City        string `json:"city"`
	StreetLine1 string `json:"street_line1"`
	StreetLine2 string `json:"street_line2"`
	PostCode    string `json:"post_code"`
}

// UserProfilePhotos represents a user's profile pictures
type UserProfilePhotos struct {
	TotalCount int            `json:"total_count"`
	Photos     [][]*PhotoSize `json:"photos"`
}

// File represents a file ready to be downloaded
type File struct {
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`
	FilePath string `json:"file_path"`
}

// ChatMember represents information about one member of a chat
type ChatMember struct {
	User                  *User  `json:"user"`
	Status                string `json:"status"`
	UntilDate             int    `json:"until_date"`
	CanBeEdited           bool   `json:"can_be_edited"`
	CanChangeInfo         bool   `json:"can_change_info"`
	CanPostMessages       bool   `json:"can_post_messages"`
	CanEditMessages       bool   `json:"can_edit_messages"`
	CanDeleteMessages     bool   `json:"can_delete_messages"`
	CanInviteUsers        bool   `json:"can_invite_users"`
	CanRestrictMembers    bool   `json:"can_restrict_members"`
	CanPinMessages        bool   `json:"can_pin_messages"`
	CanPromoteMembers     bool   `json:"can_promote_members"`
	CanSendMessages       bool   `json:"can_send_messages"`
	CanSendMediaMessages  bool   `json:"can_send_media_messages"`
	CanSendOtherMessages  bool   `json:"can_send_other_messages"`
	CanAddWebPagePreviews bool   `json:"can_add_web_page_previews"`
}

// CallbackGame is a placeholder, currently holds no information.
// Use BotFather to set up your game.
type CallbackGame struct{}

// InlineKeyboardButton represents one button of an inline keyboard.
// You must use exactly one of the optional fields.
type InlineKeyboardButton struct {
	Text                         string        `json:"text"`
	URL                          string        `json:"url"`
	CallbackData                 string        `json:"callback_data"`
	SwitchInlineQuery            string        `json:"switch_inline_query"`
	SwitchInlineQueryCurrentChat string        `json:"switch_inline_query_current_chat"`
	CallbackGame                 *CallbackGame `json:"callback_game"`
	Pay                          bool          `json:"pay"`
}

// KeyboardButton represents one button of the reply keyboard
type KeyboardButton struct {
	Text            string `json:"text"`
	RequestContact  bool   `json:"request_contact"`
	RequestLocation bool   `json:"request_location"`
}

// InlineQuery represents an incoming inline query.
// When the user sends an empty query, your bot could return some default or trending results.
type InlineQuery struct {
	ID       string    `json:"id"`
	From     *User     `json:"from"`
	Location *Location `json:"location"`
	Query    string    `json:"query"`
	Offset   string    `json:"offset"`
}

// ChosenInlineResult represents a result of an inline query
// that was chosen by the user and sent to their chat partner
type ChosenInlineResult struct {
	ResultID        string    `json:"result_id"`
	From            *User     `json:"from"`
	Location        *Location `json:"location"`
	InlineMessageID string    `json:"inline_message_id"`
	Query           string    `json:"query"`
}

// CallbackQuery represents an incoming callback query from a callback button
// in an inline keyboard. If the button that originated the query was attached
// to a message sent by the bot, the field message will be present.
type CallbackQuery struct {
	ID              string   `json:"id"`
	From            *User    `json:"from"`
	Message         *Message `json:"message"`
	InlineMessageID string   `json:"inline_message_id"`
	ChatInstance    string   `json:"chat_instance"`
	Data            string   `json:"data"`
	GameShortName   string   `json:"game_short_name"`
}

// ShippingQuery represents a shipping address
type ShippingQuery struct {
	ID              string           `json:"id"`
	From            *User            `json:"from"`
	InvoicePayload  string           `json:"invoice_payload"`
	ShippingAddress *ShippingAddress `json:"shipping_address"`
}

// PreCheckoutQuery represents information about an incoming pre-checkout query
type PreCheckoutQuery struct {
	ID               string     `json:"id"`
	From             *User      `json:"from"`
	Currency         string     `json:"currency"`
	TotalAmount      int        `json:"total_amount"`
	InvoicePayload   string     `json:"invoice_payload"`
	ShippingOptionID string     `json:"shipping_option_id"`
	OrderInfo        *OrderInfo `json:"order_info"`
}

type apiResponse struct {
	Ok          bool            `json:"ok"`
	Result      json.RawMessage `json:"result"`
	Description string          `json:"description"`
}
<commit_msg>Rearange telegram types as in API docs<commit_after>package tgbot

import "encoding/json"

// Update represents an incoming update
type Update struct {
	UpdateID           int                 `json:"update_id"`
	Message            *Message            `json:"message"`
	EditedMessage      *Message            `json:"edited_message"`
	ChannelPost        *Message            `json:"channel_post"`
	EditedChannelPost  *Message            `json:"edited_channel_post"`
	InlineQuery        *InlineQuery        `json:"inline_query"`
	ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
	CallbackQuery      *CallbackQuery      `json:"callback_query"`
	ShippingQuery      *ShippingQuery      `json:"shipping_query"`
	PreCheckoutQuery   *PreCheckoutQuery   `json:"pre_checkout_query"`
}

// WebhookInfo contains information about the current status of a webhook
type WebhookInfo struct {
	URL                  string   `json:"url"`
	HasCustomCertificate bool     `json:"has_custom_certificate"`
	PendingUpdateCount   int      `json:"pending_update_count"`
	LastErrorDate        int      `json:"last_error_date"`
	LastErrorMessage     string   `json:"last_error_message"`
	MaxConnections       int      `json:"max_connections"`
	AllowedUpdates       []string `json:"allowed_updates"`
}

// User represents a user
type User struct {
	ID           int    `json:"id"`
	IsBot        bool   `json:"is_bot"`
	FirstName    string `json:"first_name"`
	LastName     string `json:"last_name"`
	Username     string `json:"username"`
	LanguageCode string `json:"language_code"`
}

// Chat represents a chat
type Chat struct {
	ID                          int64      `json:"id"`
	Type                        string     `json:"type"`
	Title                       string     `json:"title"`
	Username                    string     `json:"username"`
	FirstName                   string     `json:"first_name"`
	LastName                    string     `json:"last_name"`
	AllMembersAreAdministrators bool       `json:"all_members_are_administrators"`
	Photo                       *ChatPhoto `json:"photo"`
	Description                 string     `json:"description"`
	InviteLink                  string     `json:"invite_link"`
	PinnedMessage               *Message   `json:"pinned_message"`
	StickerSetName              string     `json:"sticker_set_name"`
	CanSetStickerSet            bool       `json:"can_set_sticker_set"`
}

// Message represents a message
type Message struct {
	MessageID             int                `json:"message_id"`
	From                  *User              `json:"from"`
	Date                  int                `json:"date"`
	Chat                  *Chat              `json:"chat"`
	ForwardFrom           *User              `json:"forward_from"`
	ForwardFromChat       *Chat              `json:"forward_from_chat"`
	ForwardFromMessageID  int                `json:"forward_from_message_id"`
	ForwardSignature      string             `json:"forward_signature"`
	ForwardDate           int                `json:"forward_date"`
	ReplyToMessage        *Message           `json:"reply_to_message"`
	EditDate              int                `json:"edit_date"`
	MediaGroupID          string             `json:"media_group_id"`
	AuthorSignature       string             `json:"author_signature"`
	Text                  string             `json:"text"`
	Entities              []*MessageEntity   `json:"entities"`
	CaptionEntities       []*MessageEntity   `json:"caption_entities"`
	Audio                 *Audio             `json:"audio"`
	Document              *Document          `json:"document"`
	Game                  *Game              `json:"game"`
	Photo                 []*PhotoSize       `json:"photo"`
	Sticker               *Sticker           `json:"sticker"`
	Video                 *Video             `json:"video"`
	Voice                 *Voice             `json:"voice"`
	VideoNote             *VideoNote         `json:"video_note"`
	Caption               string             `json:"caption"`
	Contact               *Contact           `json:"contact"`
	Location              *Location          `json:"location"`
	Venue                 *Venue             `json:"venue"`
	NewChatMembers        []*User            `json:"new_chat_members"`
	LeftChatMember        *User              `json:"left_chat_member"`
	NewChatTitle          string             `json:"new_chat_title"`
	NewChatPhoto          []*PhotoSize       `json:"new_chat_photo"`
	DeleteChatPhoto       bool               `json:"delete_chat_photo"`
	GroupChatCreated      bool               `json:"group_chat_created"`
	SupergroupChatCreated bool               `json:"supergroup_chat_created"`
	ChannelChatCreated    bool               `json:"channel_chat_created"`
	MigrateToChatID       int64              `json:"migrate_to_chat_id"`
	MigrateFromChatID     int64              `json:"migrate_from_chat_id"`
	PinnedMessage         *Message           `json:"pinned_message"`
	Invoice               *Invoice           `json:"invoice"`
	SuccessfulPayment     *SuccessfulPayment `json:"successful_payment"`
}

// MessageEntity represents one special entity in a text message. For example, hashtags, usernames, URLs, etc.
type MessageEntity struct {
	Type   string `json:"type"`
	Offset int    `json:"offset"`
	Length int    `json:"length"`
	URL    string `json:"url"`
	User   *User  `json:"user"`
}

// PhotoSize represents one size of a photo or a file / sticker thumbnail
type PhotoSize struct {
	FileID   string `json:"file_id"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
	FileSize int    `json:"file_size"`
}

// Audio represents an audio file to be treated as music by the Telegram clients
type Audio struct {
	FileID    string `json:"file_id"`
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
	FileSize  int    `json:"file_size"`
}

// Document represents a general file (as opposed to photos, voice messages and audio files)
type Document struct {
	FileID   string     `json:"file_id"`
	Thumb    *PhotoSize `json:"thumb"`
	FileName string     `json:"file_name"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// Video represents a video file
type Video struct {
	FileID   string     `json:"file_id"`
	Width    int        `json:"width"`
	Height   int        `json:"height"`
	Duration int        `json:"duration"`
	Thumb    *PhotoSize `json:"thumb"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// Voice represents a voice note
type Voice struct {
	FileID   string `json:"file_id"`
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
	FileSize int    `json:"file_size"`
}

// VideoNote represents a video message
type VideoNote struct {
	FileID   string     `json:"file_id"`
	Length   int        `json:"length"`
	Duration int        `json:"duration"`
	Thumb    *PhotoSize `json:"thumb"`
	FileSize int        `json:"file_size"`
}

// Contact represents a phone contact
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      int    `json:"user_id"`
}

// Location represents a point on the map
type Location struct {
	Longitude float32 `json:"longitude"`
	Latitude  float32 `json:"latitude"`
}

// Venue represents a venue
type Venue struct {
	Location     *Location `json:"location"`
	Title        string    `json:"title"`
	Address      string    `json:"address"`
	FoursquareID string    `json:"foursquare_id"`
}

// UserProfilePhotos represents a user's profile pictures
type UserProfilePhotos struct {
	TotalCount int            `json:"total_count"`
	Photos     [][]*PhotoSize `json:"photos"`
}

// File represents a file ready to be downloaded
type File struct {
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`
	FilePath string `json:"file_path"`
}

// KeyboardButton represents one button of the reply keyboard
type KeyboardButton struct {
	Text            string `json:"text"`
	RequestContact  bool   `json:"request_contact"`
	RequestLocation bool   `json:"request_location"`
}

// InlineKeyboardButton represents one button of an inline keyboard.
// You must use exactly one of the optional fields.
type InlineKeyboardButton struct {
	Text                         string        `json:"text"`
	URL                          string        `json:"url"`
	CallbackData                 string        `json:"callback_data"`
	SwitchInlineQuery            string        `json:"switch_inline_query"`
	SwitchInlineQueryCurrentChat string        `json:"switch_inline_query_current_chat"`
	CallbackGame                 *CallbackGame `json:"callback_game"`
	Pay                          bool          `json:"pay"`
}

// CallbackQuery represents an incoming callback query from a callback button
// in an inline keyboard. If the button that originated the query was attached
// to a message sent by the bot, the field message will be present.
type CallbackQuery struct {
	ID              string   `json:"id"`
	From            *User    `json:"from"`
	Message         *Message `json:"message"`
	InlineMessageID string   `json:"inline_message_id"`
	ChatInstance    string   `json:"chat_instance"`
	Data            string   `json:"data"`
	GameShortName   string   `json:"game_short_name"`
}

// ChatPhoto represents a chat photo
type ChatPhoto struct {
	SmallFileID string `json:"small_file_id"`
	BigFileID   string `json:"big_file_id"`
}

// ChatMember represents information about one member of a chat
type ChatMember struct {
	User                  *User  `json:"user"`
	Status                string `json:"status"`
	UntilDate             int    `json:"until_date"`
	CanBeEdited           bool   `json:"can_be_edited"`
	CanChangeInfo         bool   `json:"can_change_info"`
	CanPostMessages       bool   `json:"can_post_messages"`
	CanEditMessages       bool   `json:"can_edit_messages"`
	CanDeleteMessages     bool   `json:"can_delete_messages"`
	CanInviteUsers        bool   `json:"can_invite_users"`
	CanRestrictMembers    bool   `json:"can_restrict_members"`
	CanPinMessages        bool   `json:"can_pin_messages"`
	CanPromoteMembers     bool   `json:"can_promote_members"`
	CanSendMessages       bool   `json:"can_send_messages"`
	CanSendMediaMessages  bool   `json:"can_send_media_messages"`
	CanSendOtherMessages  bool   `json:"can_send_other_messages"`
	CanAddWebPagePreviews bool   `json:"can_add_web_page_previews"`
}

// Sticker represents a sticker
type Sticker struct {
	FileID       string        `json:"file_id"`
	Width        int           `json:"width"`
	Height       int           `json:"height"`
	Thumb        *PhotoSize    `json:"thumb"`
	Emoji        string        `json:"emoji"`
	SetName      string        `json:"set_name"`
	MaskPosition *MaskPosition `json:"mask_position"`
	FileSize     int           `json:"file_size"`
}

// StickerSet represents a sticker set
type StickerSet struct {
	Name          string     `json:"name"`
	Title         string     `json:"title"`
	ContainsMasks bool       `json:"contains_masks"`
	Stickers      []*Sticker `json:"stickers"`
}

// MaskPosition describes the position on faces where a mask should be placed by default.
// TODO: Turn it into a method.
type MaskPosition struct {
	Point  string  `json:"point"`
	XShift float32 `json:"x_shift"`
	YShift float32 `json:"y_shift"`
	Scale  float32 `json:"scale"`
}

// Game represents a game.
// Use BotFather to create and edit games, their short names will act as unique identifiers.
type Game struct {
	Title        string           `json:"title"`
	Description  string           `json:"description"`
	Photo        []*PhotoSize     `json:"photo"`
	Text         string           `json:"text"`
	TextEntities []*MessageEntity `json:"text_entities"`
	Animation    *Animation       `json:"animation"`
}

// Animation represents an animation file to be displayed in the message containing a game
type Animation struct {
	FileID   string     `json:"file_id"`
	Thumb    *PhotoSize `json:"thumb"`
	FileName string     `json:"file_name"`
	MimeType string     `json:"mime_type"`
	FileSize int        `json:"file_size"`
}

// Invoice contains basic information about a invoice
type Invoice struct {
	Title          string `json:"title"`
	Description    string `json:"description"`
	StartParameter string `json:"start_parameter"`
	Currency       string `json:"currency"`
	TotalAmount    int    `json:"total_amount"`
}

// SuccessfulPayment contains basic information about a successful payment
type SuccessfulPayment struct {
	Currency                string     `json:"currency"`
	TotalAmount             int        `json:"total_amount"`
	InvoicePayload          string     `json:"invoice_payload"`
	ShippingOptionID        string     `json:"shipping_option_id"`
	OrderInfo               *OrderInfo `json:"order_info"`
	TelegramPaymentChargeID string     `json:"telegram_payment_charge_id"`
	ProviderPaymentChargeID string     `json:"provider_payment_charge_id"`
}

// OrderInfo represents information about an order
type OrderInfo struct {
	Name            string           `json:"name"`
	PhoneNumber     string           `json:"phone_number"`
	Email           string           `json:"email"`
	ShippingAddress *ShippingAddress `json:"shipping_address"`
}

// ShippingAddress represents a shipping address
type ShippingAddress struct {
	CountryCode string `json:"country_code"`
	State       string `json:"state"`
	City        string `json:"city"`
	StreetLine1 string `json:"street_line1"`
	StreetLine2 string `json:"street_line2"`
	PostCode    string `json:"post_code"`
}

// CallbackGame is a placeholder, currently holds no information.
// Use BotFather to set up your game.
type CallbackGame struct{}

// InlineQuery represents an incoming inline query.
// When the user sends an empty query, your bot could return some default or trending results.
type InlineQuery struct {
	ID       string    `json:"id"`
	From     *User     `json:"from"`
	Location *Location `json:"location"`
	Query    string    `json:"query"`
	Offset   string    `json:"offset"`
}

// ChosenInlineResult represents a result of an inline query
// that was chosen by the user and sent to their chat partner
type ChosenInlineResult struct {
	ResultID        string    `json:"result_id"`
	From            *User     `json:"from"`
	Location        *Location `json:"location"`
	InlineMessageID string    `json:"inline_message_id"`
	Query           string    `json:"query"`
}

// ShippingQuery represents a shipping address
type ShippingQuery struct {
	ID              string           `json:"id"`
	From            *User            `json:"from"`
	InvoicePayload  string           `json:"invoice_payload"`
	ShippingAddress *ShippingAddress `json:"shipping_address"`
}

// PreCheckoutQuery represents information about an incoming pre-checkout query
type PreCheckoutQuery struct {
	ID               string     `json:"id"`
	From             *User      `json:"from"`
	Currency         string     `json:"currency"`
	TotalAmount      int        `json:"total_amount"`
	InvoicePayload   string     `json:"invoice_payload"`
	ShippingOptionID string     `json:"shipping_option_id"`
	OrderInfo        *OrderInfo `json:"order_info"`
}

type apiResponse struct {
	Ok          bool            `json:"ok"`
	Result      json.RawMessage `json:"result"`
	Description string          `json:"description"`
}
<|endoftext|>


<commit_before>package telebot

import "strconv"

// Recipient is basically any possible endpoint you can send
// messages to. It's usually a distinct user or a chat.
type Recipient interface {
	// ID of user or group chat, @Username for channel
	Destination() string
}

// User object represents a Telegram user, bot
//
// object represents a group chat if Title is empty.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`

	LastName string `json:"last_name"`
	Username string `json:"username"`
}

// Destination is internal user ID.
func (u User) Destination() string {
	return strconv.Itoa(u.ID)
}

// Chat object represents a Telegram user, bot or group chat.
// Title for channels and group chats
// Type of chat, can be either “private”, “group”, "supergroup" or “channel”
type Chat struct {
	ID   int64  `json:"id"`
	Type string `json:"type"`

	Title     string `json:"title"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
}

// Destination is internal chat ID.
func (c Chat) Destination() string {
	ret := "@" + c.Username
	if c.Type != "channel" {
		ret = strconv.FormatInt(c.ID, 10)
	}
	return ret
}

// IsGroupChat returns true if chat object represents a group chat.
func (c Chat) IsGroupChat() bool {
	return c.Type != "private"
}

// Update object represents an incoming update.
type Update struct {
	ID      int      `json:"update_id"`
	Payload *Message `json:"message"`

	// optional
	Callback *Callback `json:"callback_query"`
	Query    *Query    `json:"inline_query"`
}

// Thumbnail object represents an image/sticker of a particular size.
type Thumbnail struct {
	File

	Width  int `json:"width"`
	Height int `json:"height"`
}

// Photo object represents a photo with caption.
type Photo struct {
	File

	Thumbnail

	Caption string
}

// Audio object represents an audio file (voice note).
type Audio struct {
	File

	// Duration of the recording in seconds as defined by sender.
	Duration int `json:"duration"`

	// MIME type of the file as defined by sender.
	Mime string `json:"mime_type"`
}

// Document object represents a general file (as opposed to Photo or Audio).
// Telegram users can send files of any type of up to 1.5 GB in size.
type Document struct {
	File

	// Document thumbnail as defined by sender.
	Preview Thumbnail `json:"thumb"`

	// Original filename as defined by sender.
	FileName string `json:"file_name"`

	// MIME type of the file as defined by sender.
	Mime string `json:"mime_type"`
}

// Sticker object represents a WebP image, so-called sticker.
type Sticker struct {
	File

	Width  int `json:"width"`
	Height int `json:"height"`

	// Sticker thumbnail in .webp or .jpg format.
	Preview Thumbnail `json:"thumb"`
}

// Video object represents an MP4-encoded video.
type Video struct {
	Audio

	Width  int `json:"width"`
	Height int `json:"height"`

	// Text description of the video as defined by sender (usually empty).
	Caption string `json:"caption"`

	// Video thumbnail.
	Preview Thumbnail `json:"thumb"`
}

// KeyboardButton represents a button displayed on in a message.
type KeyboardButton struct {
	Text        string `json:"text"`
	URL         string `json:"url,omitempty"`
	Data        string `json:"callback_data,omitempty"`
	InlineQuery string `json:"switch_inline_query,omitempty"`
}

// InlineKeyboardMarkup represents an inline keyboard that appears right next
// to the message it belongs to.
type InlineKeyboardMarkup struct {
	// Array of button rows, each represented by an Array of KeyboardButton objects.
	InlineKeyboard [][]KeyboardButton `json:"inline_keyboard,omitempty"`
}

// Contact object represents a contact to Telegram user
type Contact struct {
	UserID      int    `json:"user_id"`
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
}

// Location object represents geographic position.
type Location struct {
	Longitude float32 `json:"longitude"`
	Latitude  float32 `json:"latitude"`
}

// Callback object represents a query from a callback button in an
// inline keyboard.
type Callback struct {
	ID string `json:"id"`

	// For message sent to channels, Sender may be empty
	Sender User `json:"from"`

	// Message will be set if the button that originated the query
	// was attached to a message sent by a bot.
	Message Message `json:"message"`

	// MessageID will be set if the button was attached to a message
	// sent via the bot in inline mode.
	MessageID string `json:"inline_message_id"`
	Data      string `json:"data"`
}

// CallbackResponse builds a response to an Callback query.
// See also: https://core.telegram.org/bots/api#answerCallbackQuery
type CallbackResponse struct {
	// The ID of the callback to which this is a response.
	// It is not necessary to specify this field manually.
	CallbackID string `json:"callback_query_id"`

	// Text of the notification. If not specified, nothing will be shown to the user.
	Text string `json:"text,omitempty"`

	// (Optional) If true, an alert will be shown by the client instead
	// of a notification at the top of the chat screen. Defaults to false.
	ShowAlert bool `json:"show_alert,omitempty"`
}

// Venue object represents a venue location with name, address and optional foursquare id.
type Venue struct {
	Location      Location `json:"location"`
	Title         string   `json:"title"`
	Address       string   `json:"address"`
	Foursquare_id string   `json:"foursquare_id",omitempty`
}

// MessageEntity
// This object represents one special entity in a text message.
// For example, hashtags, usernames, URLs, etc
type MessageEntity struct {

	// type Type of the entity. Can be mention (@username), hashtag,
	// bot_command, url, email, bold (bold text), italic (italic text),
	// code (monowidth string), pre (monowidth block), text_link (for clickable text URLs),
	// text_mention (for users without usernames)
	Type string `json:"type"`

	// offset Offset in UTF-16 code units to the start of the entity
	Offset int `json:"offset"`

	//length Length of the entity in UTF-16 code units
	Length int `json:"length"`

	//url	Optional. For “text_link” only, url that will be opened after user taps on the text
	Url string `json:"url",omitempty`

	//user	Optional. For “text_mention” only, the mentioned user
	User User `json:"user",omitempty`
}
<commit_msg>Sequence Location field<commit_after>package telebot

import "strconv"

// Recipient is basically any possible endpoint you can send
// messages to. It's usually a distinct user or a chat.
type Recipient interface {
	// ID of user or group chat, @Username for channel
	Destination() string
}

// User object represents a Telegram user, bot
//
// object represents a group chat if Title is empty.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`

	LastName string `json:"last_name"`
	Username string `json:"username"`
}

// Destination is internal user ID.
func (u User) Destination() string {
	return strconv.Itoa(u.ID)
}

// Chat object represents a Telegram user, bot or group chat.
// Title for channels and group chats
// Type of chat, can be either “private”, “group”, "supergroup" or “channel”
type Chat struct {
	ID   int64  `json:"id"`
	Type string `json:"type"`

	Title     string `json:"title"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
}

// Destination is internal chat ID.
func (c Chat) Destination() string {
	ret := "@" + c.Username
	if c.Type != "channel" {
		ret = strconv.FormatInt(c.ID, 10)
	}
	return ret
}

// IsGroupChat returns true if chat object represents a group chat.
func (c Chat) IsGroupChat() bool {
	return c.Type != "private"
}

// Update object represents an incoming update.
type Update struct {
	ID      int      `json:"update_id"`
	Payload *Message `json:"message"`

	// optional
	Callback *Callback `json:"callback_query"`
	Query    *Query    `json:"inline_query"`
}

// Thumbnail object represents an image/sticker of a particular size.
type Thumbnail struct {
	File

	Width  int `json:"width"`
	Height int `json:"height"`
}

// Photo object represents a photo with caption.
type Photo struct {
	File

	Thumbnail

	Caption string
}

// Audio object represents an audio file (voice note).
type Audio struct {
	File

	// Duration of the recording in seconds as defined by sender.
	Duration int `json:"duration"`

	// MIME type of the file as defined by sender.
	Mime string `json:"mime_type"`
}

// Document object represents a general file (as opposed to Photo or Audio).
// Telegram users can send files of any type of up to 1.5 GB in size.
type Document struct {
	File

	// Document thumbnail as defined by sender.
	Preview Thumbnail `json:"thumb"`

	// Original filename as defined by sender.
	FileName string `json:"file_name"`

	// MIME type of the file as defined by sender.
	Mime string `json:"mime_type"`
}

// Sticker object represents a WebP image, so-called sticker.
type Sticker struct {
	File

	Width  int `json:"width"`
	Height int `json:"height"`

	// Sticker thumbnail in .webp or .jpg format.
	Preview Thumbnail `json:"thumb"`
}

// Video object represents an MP4-encoded video.
type Video struct {
	Audio

	Width  int `json:"width"`
	Height int `json:"height"`

	// Text description of the video as defined by sender (usually empty).
	Caption string `json:"caption"`

	// Video thumbnail.
	Preview Thumbnail `json:"thumb"`
}

// KeyboardButton represents a button displayed on in a message.
type KeyboardButton struct {
	Text        string `json:"text"`
	URL         string `json:"url,omitempty"`
	Data        string `json:"callback_data,omitempty"`
	InlineQuery string `json:"switch_inline_query,omitempty"`
}

// InlineKeyboardMarkup represents an inline keyboard that appears right next
// to the message it belongs to.
type InlineKeyboardMarkup struct {
	// Array of button rows, each represented by an Array of KeyboardButton objects.
	InlineKeyboard [][]KeyboardButton `json:"inline_keyboard,omitempty"`
}

// Contact object represents a contact to Telegram user
type Contact struct {
	UserID      int    `json:"user_id"`
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
}

// Location object represents geographic position.
type Location struct {
	Latitude  float32 `json:"latitude"`
	Longitude float32 `json:"longitude"`
}

// Callback object represents a query from a callback button in an
// inline keyboard.
type Callback struct {
	ID string `json:"id"`

	// For message sent to channels, Sender may be empty
	Sender User `json:"from"`

	// Message will be set if the button that originated the query
	// was attached to a message sent by a bot.
	Message Message `json:"message"`

	// MessageID will be set if the button was attached to a message
	// sent via the bot in inline mode.
	MessageID string `json:"inline_message_id"`
	Data      string `json:"data"`
}

// CallbackResponse builds a response to an Callback query.
// See also: https://core.telegram.org/bots/api#answerCallbackQuery
type CallbackResponse struct {
	// The ID of the callback to which this is a response.
	// It is not necessary to specify this field manually.
	CallbackID string `json:"callback_query_id"`

	// Text of the notification. If not specified, nothing will be shown to the user.
	Text string `json:"text,omitempty"`

	// (Optional) If true, an alert will be shown by the client instead
	// of a notification at the top of the chat screen. Defaults to false.
	ShowAlert bool `json:"show_alert,omitempty"`
}

// Venue object represents a venue location with name, address and optional foursquare id.
type Venue struct {
	Location      Location `json:"location"`
	Title         string   `json:"title"`
	Address       string   `json:"address"`
	Foursquare_id string   `json:"foursquare_id",omitempty`
}

// MessageEntity
// This object represents one special entity in a text message.
// For example, hashtags, usernames, URLs, etc
type MessageEntity struct {

	// type Type of the entity. Can be mention (@username), hashtag,
	// bot_command, url, email, bold (bold text), italic (italic text),
	// code (monowidth string), pre (monowidth block), text_link (for clickable text URLs),
	// text_mention (for users without usernames)
	Type string `json:"type"`

	// offset Offset in UTF-16 code units to the start of the entity
	Offset int `json:"offset"`

	//length Length of the entity in UTF-16 code units
	Length int `json:"length"`

	//url	Optional. For “text_link” only, url that will be opened after user taps on the text
	Url string `json:"url",omitempty`

	//user	Optional. For “text_mention” only, the mentioned user
	User User `json:"user",omitempty`
}
<|endoftext|>


<commit_before>package parse

import (
	"encoding/json"
	"fmt"
	"net/url"
	"path"
	"reflect"
	"time"
)

// An interface for custom Parse types. Contains a single method:
//
// ClassName() - returns a string containing the class name as it appears in your
// Parse database.
//
// Implement this interface if your class name does not match your struct
// name. If this class is not implemented, the name of the struct will
// be used when interacting with the Parse API
type iClassName interface {
	ClassName() string
}

// An interface for custom Parse types to override the endpoint used for querying.
//
// Contains a single method:
//
// Endpoint() - returns the endpoint to use when querying the Parse REST API.
//
// If this method is not implented, the endpoint is constructed as follows:
//
// /classes/{ClassName} - where {ClassName} is the name of the struct or the value returned by the ClassName
// method if implemented
type iParseEp interface {
	Endpoint() string
}

// A base type containing fields common to all Parse types
//
// Embed this struct in custom types to avoid having to declare
// these fields everywhere.
type Base struct {
	Id        string                 `parse:"objectId"`
	CreatedAt time.Time              `parse:"-"`
	UpdatedAt time.Time              `parse:"-"`
	ACL       ACL                    `parse:"ACL,omitempty"`
	Extra     map[string]interface{} `parse:"-"`
}

// Represents the built-in Parse "User" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type User struct {
	Base
	Username      string
	Email         string
	EmailVerified bool
}

func (u *User) ClassName() string {
	return "_User"
}

func (u *User) Endpoint() string {
	return "users"
}

// Represents the built-in Parse "Installation" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type Installation struct {
	Base
}

func (i *Installation) ClassName() string {
	return "_Installation"
}

func (i *Installation) Endpoint() string {
	return "installations"
}

type ACL interface {
	// Returns whether public read access is enabled on this ACL
	PublicReadAccess() bool

	// Returns whether public write access is enabled on this ACL
	PublicWriteAccess() bool

	// Returns whether read access is enabled on this ACL for the
	// given role
	RoleReadAccess(role string) bool

	// Returns whether write access is enabled on this ACL for the
	// given role
	RoleWriteAccess(role string) bool

	// Returns whether read access is enabled on this ACL for the
	// given user
	ReadAccess(userId string) bool

	// Returns whether write access is enabled on this ACL for the
	// given user
	WriteAccess(userId string) bool

	// Allow the object to which this ACL is attached be read
	// by anyone
	SetPublicReadAccess(allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by anyone
	SetPublicWriteAccess(allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// read by the provided role
	SetRoleReadAccess(role string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by the provided role
	SetRoleWriteAccess(role string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// read by the provided user
	SetReadAccess(userId string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by the provided user
	SetWriteAccess(userId string, allowed bool) ACL
}

type aclT struct {
	publicReadAccess  bool
	publicWriteAccess bool

	write map[string]bool
	read  map[string]bool
}

func NewACL() ACL {
	return &aclT{
		write: map[string]bool{},
		read:  map[string]bool{},
	}
}

func (a *aclT) PublicReadAccess() bool {
	return a.publicReadAccess
}

func (a *aclT) PublicWriteAccess() bool {
	return a.publicWriteAccess
}

func (a *aclT) RoleReadAccess(role string) bool {
	if tmp, ok := a.read["role:"+role]; ok {
		return tmp
	}
	return false
}

func (a *aclT) RoleWriteAccess(role string) bool {
	if tmp, ok := a.write["role:"+role]; ok {
		return tmp
	}
	return false
}

func (a *aclT) ReadAccess(userId string) bool {
	if tmp, ok := a.read[userId]; ok {
		return tmp
	}
	return false
}

func (a *aclT) WriteAccess(userId string) bool {
	if tmp, ok := a.write[userId]; ok {
		return tmp
	}
	return false
}

func (a *aclT) SetPublicReadAccess(allowed bool) ACL {
	a.publicReadAccess = allowed
	return a
}

func (a *aclT) SetPublicWriteAccess(allowed bool) ACL {
	a.publicWriteAccess = allowed
	return a
}

func (a *aclT) SetReadAccess(userId string, allowed bool) ACL {
	a.read[userId] = allowed
	return a
}

func (a *aclT) SetWriteAccess(userId string, allowed bool) ACL {
	a.write[userId] = allowed
	return a
}

func (a *aclT) SetRoleReadAccess(role string, allowed bool) ACL {
	a.read["role:"+role] = allowed
	return a
}

func (a *aclT) SetRoleWriteAccess(role string, allowed bool) ACL {
	a.write["role:"+role] = allowed
	return a
}

func (a *aclT) MarshalJSON() ([]byte, error) {
	m := map[string]map[string]bool{}

	for k, v := range a.read {
		if v {
			m[k] = map[string]bool{
				"read": v,
			}
		}
	}

	for k, v := range a.write {
		if v {
			if p, ok := m[k]; ok {
				p["write"] = v
			} else {
				m[k] = map[string]bool{
					"write": v,
				}
			}
		}
	}

	if a.publicReadAccess {
		m["*"] = map[string]bool{
			"read": true,
		}
	}

	if a.publicWriteAccess {
		if p, ok := m["*"]; !ok {
			m["*"] = map[string]bool{
				"write": true,
			}
		} else {
			p["write"] = true
		}
	}

	return json.Marshal(m)
}

func (a *aclT) UnmarshalJSON(b []byte) error {
	m := map[string]map[string]bool{}

	if err := json.Unmarshal(b, &m); err != nil {
		return err
	}

	if a.read == nil {
		a.read = map[string]bool{}
	}

	if a.write == nil {
		a.write = map[string]bool{}
	}

	for k, v := range m {
		if k == "*" {
			if w, ok := v["write"]; w && ok {
				a.publicWriteAccess = true
			}
			if r, ok := v["read"]; r && ok {
				a.publicReadAccess = true
			}
		} else {
			if w, ok := v["write"]; w && ok {
				a.write[k] = true
			}
			if r, ok := v["read"]; r && ok {
				a.read[k] = true
			}
		}
	}
	return nil
}

// Represents the Parse GeoPoint type
type GeoPoint struct {
	Latitude  float64
	Longitude float64
}

func (g GeoPoint) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{
		"GeoPoint",
		g.Latitude,
		g.Longitude,
	})
}

func (g *GeoPoint) UnmarshalJSON(b []byte) error {
	s := struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "GeoPoint" {
		return fmt.Errorf("cannot unmarshal type %s to type GeoPoint", s.Type)
	}

	g.Latitude = s.Latitude
	g.Longitude = s.Longitude
	return nil
}

// Represents the Parse File type
type File struct {
}

// Represents a Parse Pointer type. When querying, creating, or updating
// objects, any struct types will be automatically converted to and from Pointer
// types as required. Direct use of this type should not be necessary
type Pointer struct {
	Id        string
	ClassName string
}

func (p Pointer) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string `json:"__type"`
		ClassName string `json:"className"`
		Id        string `json:"objectId"`
	}{
		"Pointer",
		p.ClassName,
		p.Id,
	})
}

// Represents the Parse Date type. Values of type time.Time will
// automatically converted to a Date type when constructing queries
// or creating objects. The inverse is true for retrieving objects.
// Direct use of this type should not be necessary
type Date time.Time

func (d Date) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{
		"Date",
		time.Time(d).In(time.UTC).Format("2006-01-02T15:04:05.000Z"),
	})
}

func (d *Date) UnmarshalJSON(b []byte) error {
	s := struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "Date" {
		return fmt.Errorf("cannot unmarshal type %s to type Date", s.Type)
	}

	t, err := time.Parse("2006-01-02T15:04:05.000Z", s.Iso)
	if err != nil {
		return err
	}

	*d = Date(t)
	return nil
}

func getClassName(v interface{}) string {
	if tmp, ok := v.(iClassName); ok {
		return tmp.ClassName()
	} else {
		t := reflect.TypeOf(v)
		return t.Elem().Name()
	}
}

func getEndpointBase(v interface{}) string {
	var p string
	var inst interface{}

	rt := reflect.TypeOf(v)
	rt = rt.Elem()
	if rt.Kind() == reflect.Slice || rt.Kind() == reflect.Array {
		rte := rt.Elem()
		var rv reflect.Value
		if rte.Kind() == reflect.Ptr {
			rv = reflect.New(rte.Elem())
		} else {
			rv = reflect.New(rte)
		}
		inst = rv.Interface()
	} else {
		inst = v
	}

	if iv, ok := inst.(iParseEp); ok {
		p = iv.Endpoint()
	} else {
		cname := getClassName(v)
		p = path.Join("classes", cname)
	}

	p = path.Join(ParseVersion, p)
	return p
}

type Config map[string]interface{}

type configRequestT struct{}

func (c *configRequestT) method() string {
	return "GET"
}

func (c *configRequestT) endpoint() (string, error) {
	u := url.URL{}
	u.Scheme = "https"
	u.Host = parseHost
	u.Path = path.Join(ParseVersion, "config")
	return u.String(), nil
}

func (c *configRequestT) body() (string, error) {
	return "", nil
}

func (c *configRequestT) useMasterKey() bool {
	return false
}

func (c *configRequestT) session() *sessionT {
	return nil
}

func (c *configRequestT) contentType() string {
	return ""
}

func GetConfig() (Config, error) {
	b, err := defaultClient.doRequest(&configRequestT{})
	if err != nil {
		return nil, err
	}

	c := struct {
		Params Config `json:"params"`
	}{}
	if err := json.Unmarshal(b, &c); err != nil {
		return nil, err
	}

	return c.Params, nil
}
<commit_msg>add built-in installation fields to the installation type<commit_after>package parse

import (
	"encoding/json"
	"fmt"
	"net/url"
	"path"
	"reflect"
	"time"
)

// An interface for custom Parse types. Contains a single method:
//
// ClassName() - returns a string containing the class name as it appears in your
// Parse database.
//
// Implement this interface if your class name does not match your struct
// name. If this class is not implemented, the name of the struct will
// be used when interacting with the Parse API
type iClassName interface {
	ClassName() string
}

// An interface for custom Parse types to override the endpoint used for querying.
//
// Contains a single method:
//
// Endpoint() - returns the endpoint to use when querying the Parse REST API.
//
// If this method is not implented, the endpoint is constructed as follows:
//
// /classes/{ClassName} - where {ClassName} is the name of the struct or the value returned by the ClassName
// method if implemented
type iParseEp interface {
	Endpoint() string
}

// A base type containing fields common to all Parse types
//
// Embed this struct in custom types to avoid having to declare
// these fields everywhere.
type Base struct {
	Id        string                 `parse:"objectId"`
	CreatedAt time.Time              `parse:"-"`
	UpdatedAt time.Time              `parse:"-"`
	ACL       ACL                    `parse:"ACL,omitempty"`
	Extra     map[string]interface{} `parse:"-"`
}

// Represents the built-in Parse "User" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type User struct {
	Base
	Username      string
	Email         string
	EmailVerified bool
}

func (u *User) ClassName() string {
	return "_User"
}

func (u *User) Endpoint() string {
	return "users"
}

// Represents the built-in Parse "Installation" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type Installation struct {
	Base
	Badge          int      `parse:",omitempty"`
	Channels       []string `parse:",omitempty"`
	TimeZone       string
	DeviceType     string
	PushType       string `parse:",omitempty"`
	GCMSenderId    string `parse:",omitempty"`
	InstallationId string
	DeviceToken    string   `parse:",omitempty"`
	ChannelUris    []string `parse:",omitempty"`
	AppName        string
	AppVersion     string
	ParseVersion   string
	AppIdentifier  string
}

func (i *Installation) ClassName() string {
	return "_Installation"
}

func (i *Installation) Endpoint() string {
	return "installations"
}

type ACL interface {
	// Returns whether public read access is enabled on this ACL
	PublicReadAccess() bool

	// Returns whether public write access is enabled on this ACL
	PublicWriteAccess() bool

	// Returns whether read access is enabled on this ACL for the
	// given role
	RoleReadAccess(role string) bool

	// Returns whether write access is enabled on this ACL for the
	// given role
	RoleWriteAccess(role string) bool

	// Returns whether read access is enabled on this ACL for the
	// given user
	ReadAccess(userId string) bool

	// Returns whether write access is enabled on this ACL for the
	// given user
	WriteAccess(userId string) bool

	// Allow the object to which this ACL is attached be read
	// by anyone
	SetPublicReadAccess(allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by anyone
	SetPublicWriteAccess(allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// read by the provided role
	SetRoleReadAccess(role string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by the provided role
	SetRoleWriteAccess(role string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// read by the provided user
	SetReadAccess(userId string, allowed bool) ACL

	// Allow the object to which this ACL is attached to be
	// updated by the provided user
	SetWriteAccess(userId string, allowed bool) ACL
}

type aclT struct {
	publicReadAccess  bool
	publicWriteAccess bool

	write map[string]bool
	read  map[string]bool
}

func NewACL() ACL {
	return &aclT{
		write: map[string]bool{},
		read:  map[string]bool{},
	}
}

func (a *aclT) PublicReadAccess() bool {
	return a.publicReadAccess
}

func (a *aclT) PublicWriteAccess() bool {
	return a.publicWriteAccess
}

func (a *aclT) RoleReadAccess(role string) bool {
	if tmp, ok := a.read["role:"+role]; ok {
		return tmp
	}
	return false
}

func (a *aclT) RoleWriteAccess(role string) bool {
	if tmp, ok := a.write["role:"+role]; ok {
		return tmp
	}
	return false
}

func (a *aclT) ReadAccess(userId string) bool {
	if tmp, ok := a.read[userId]; ok {
		return tmp
	}
	return false
}

func (a *aclT) WriteAccess(userId string) bool {
	if tmp, ok := a.write[userId]; ok {
		return tmp
	}
	return false
}

func (a *aclT) SetPublicReadAccess(allowed bool) ACL {
	a.publicReadAccess = allowed
	return a
}

func (a *aclT) SetPublicWriteAccess(allowed bool) ACL {
	a.publicWriteAccess = allowed
	return a
}

func (a *aclT) SetReadAccess(userId string, allowed bool) ACL {
	a.read[userId] = allowed
	return a
}

func (a *aclT) SetWriteAccess(userId string, allowed bool) ACL {
	a.write[userId] = allowed
	return a
}

func (a *aclT) SetRoleReadAccess(role string, allowed bool) ACL {
	a.read["role:"+role] = allowed
	return a
}

func (a *aclT) SetRoleWriteAccess(role string, allowed bool) ACL {
	a.write["role:"+role] = allowed
	return a
}

func (a *aclT) MarshalJSON() ([]byte, error) {
	m := map[string]map[string]bool{}

	for k, v := range a.read {
		if v {
			m[k] = map[string]bool{
				"read": v,
			}
		}
	}

	for k, v := range a.write {
		if v {
			if p, ok := m[k]; ok {
				p["write"] = v
			} else {
				m[k] = map[string]bool{
					"write": v,
				}
			}
		}
	}

	if a.publicReadAccess {
		m["*"] = map[string]bool{
			"read": true,
		}
	}

	if a.publicWriteAccess {
		if p, ok := m["*"]; !ok {
			m["*"] = map[string]bool{
				"write": true,
			}
		} else {
			p["write"] = true
		}
	}

	return json.Marshal(m)
}

func (a *aclT) UnmarshalJSON(b []byte) error {
	m := map[string]map[string]bool{}

	if err := json.Unmarshal(b, &m); err != nil {
		return err
	}

	if a.read == nil {
		a.read = map[string]bool{}
	}

	if a.write == nil {
		a.write = map[string]bool{}
	}

	for k, v := range m {
		if k == "*" {
			if w, ok := v["write"]; w && ok {
				a.publicWriteAccess = true
			}
			if r, ok := v["read"]; r && ok {
				a.publicReadAccess = true
			}
		} else {
			if w, ok := v["write"]; w && ok {
				a.write[k] = true
			}
			if r, ok := v["read"]; r && ok {
				a.read[k] = true
			}
		}
	}
	return nil
}

// Represents the Parse GeoPoint type
type GeoPoint struct {
	Latitude  float64
	Longitude float64
}

func (g GeoPoint) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{
		"GeoPoint",
		g.Latitude,
		g.Longitude,
	})
}

func (g *GeoPoint) UnmarshalJSON(b []byte) error {
	s := struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "GeoPoint" {
		return fmt.Errorf("cannot unmarshal type %s to type GeoPoint", s.Type)
	}

	g.Latitude = s.Latitude
	g.Longitude = s.Longitude
	return nil
}

// Represents the Parse File type
type File struct {
}

// Represents a Parse Pointer type. When querying, creating, or updating
// objects, any struct types will be automatically converted to and from Pointer
// types as required. Direct use of this type should not be necessary
type Pointer struct {
	Id        string
	ClassName string
}

func (p Pointer) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string `json:"__type"`
		ClassName string `json:"className"`
		Id        string `json:"objectId"`
	}{
		"Pointer",
		p.ClassName,
		p.Id,
	})
}

// Represents the Parse Date type. Values of type time.Time will
// automatically converted to a Date type when constructing queries
// or creating objects. The inverse is true for retrieving objects.
// Direct use of this type should not be necessary
type Date time.Time

func (d Date) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{
		"Date",
		time.Time(d).In(time.UTC).Format("2006-01-02T15:04:05.000Z"),
	})
}

func (d *Date) UnmarshalJSON(b []byte) error {
	s := struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "Date" {
		return fmt.Errorf("cannot unmarshal type %s to type Date", s.Type)
	}

	t, err := time.Parse("2006-01-02T15:04:05.000Z", s.Iso)
	if err != nil {
		return err
	}

	*d = Date(t)
	return nil
}

func getClassName(v interface{}) string {
	if tmp, ok := v.(iClassName); ok {
		return tmp.ClassName()
	} else {
		t := reflect.TypeOf(v)
		return t.Elem().Name()
	}
}

func getEndpointBase(v interface{}) string {
	var p string
	var inst interface{}

	rt := reflect.TypeOf(v)
	rt = rt.Elem()
	if rt.Kind() == reflect.Slice || rt.Kind() == reflect.Array {
		rte := rt.Elem()
		var rv reflect.Value
		if rte.Kind() == reflect.Ptr {
			rv = reflect.New(rte.Elem())
		} else {
			rv = reflect.New(rte)
		}
		inst = rv.Interface()
	} else {
		inst = v
	}

	if iv, ok := inst.(iParseEp); ok {
		p = iv.Endpoint()
	} else {
		cname := getClassName(v)
		p = path.Join("classes", cname)
	}

	p = path.Join(ParseVersion, p)
	return p
}

type Config map[string]interface{}

type configRequestT struct{}

func (c *configRequestT) method() string {
	return "GET"
}

func (c *configRequestT) endpoint() (string, error) {
	u := url.URL{}
	u.Scheme = "https"
	u.Host = parseHost
	u.Path = path.Join(ParseVersion, "config")
	return u.String(), nil
}

func (c *configRequestT) body() (string, error) {
	return "", nil
}

func (c *configRequestT) useMasterKey() bool {
	return false
}

func (c *configRequestT) session() *sessionT {
	return nil
}

func (c *configRequestT) contentType() string {
	return ""
}

func GetConfig() (Config, error) {
	b, err := defaultClient.doRequest(&configRequestT{})
	if err != nil {
		return nil, err
	}

	c := struct {
		Params Config `json:"params"`
	}{}
	if err := json.Unmarshal(b, &c); err != nil {
		return nil, err
	}

	return c.Params, nil
}
<|endoftext|>


<commit_before>package dbr

import (
	"database/sql"
	"encoding/json"
)

type NullString struct {
	sql.NullString
}

type NullInt64 struct {
	sql.NullInt64
}

func (n *NullString) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.String)
		return j, e
	}
	return []byte("null"), nil
}

func (n *NullInt64) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Int64)
		return j, e
	}
	return []byte("null"), nil
}<commit_msg>Timestamps<commit_after>package dbr

import (
	"database/sql"
	"encoding/json"
	"github.com/go-sql-driver/mysql"
)

type NullString struct {
	sql.NullString
}

type NullInt64 struct {
	sql.NullInt64
}

type NullTime struct {
	mysql.NullTime
}

var nullString = []byte("null")

func (n *NullString) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.String)
		return j, e
	}
	return nullString, nil
}

func (n *NullInt64) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Int64)
		return j, e
	}
	return nullString, nil
}

func (n *NullTime) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Time)
		return j, e
	}
	return nullString, nil
}<|endoftext|>


<commit_before>package prosemirror

type EditorState struct {
	Doc       *Content   `json:"doc"`
	Selection *Selection `json:"selection"`
}

type Content struct {
	Attrs   map[string]interface{} `json:"attrs,omitempty"`
	Content []*Content             `json:"content,omitempty"`
	Marks   []*Mark                `json:"marks,omitempty"`
	Text    string                 `json:"text,omitempty"`
	Type    string                 `json:"type"`
}

type Selection struct {
	Anchor int    `json:"anchor"`
	Head   int    `json:"head"`
	Type   string `json:"type"`
}

type Mark struct {
	Attrs map[string]interface{} `json:"attrs,omitempty"`
	Type  string                 `json:"type"`
}
<commit_msg>adding more docs to types<commit_after>package prosemirror

// EditorState - http://prosemirror.net/docs/ref/#state.Editor_State
type EditorState struct {
	Doc       *Content   `json:"doc"`
	Selection *Selection `json:"selection"`
}

// Content - http://prosemirror.net/docs/ref/#model.Node
type Content struct {
	Attrs   map[string]interface{} `json:"attrs,omitempty"`
	Content []*Content             `json:"content,omitempty"`
	Marks   []*Mark                `json:"marks,omitempty"`
	Text    string                 `json:"text,omitempty"`
	Type    string                 `json:"type"`
}

// Selection - http://prosemirror.net/docs/ref/#state.Selection
type Selection struct {
	Anchor int    `json:"anchor"`
	Head   int    `json:"head"`
	Type   string `json:"type"`
}

// Mark - http://prosemirror.net/docs/ref/#model.Mark
type Mark struct {
	Attrs map[string]interface{} `json:"attrs,omitempty"`
	Type  string                 `json:"type"`
}
<|endoftext|>


<commit_before>package commands

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"

	//ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
	//bs "github.com/ipfs/go-ipfs/blocks/blockstore"
	k "github.com/ipfs/go-ipfs/blocks/key"
	cmds "github.com/ipfs/go-ipfs/commands"
	"github.com/ipfs/go-ipfs/core"
	"github.com/ipfs/go-ipfs/filestore"
	fsutil "github.com/ipfs/go-ipfs/filestore/util"
	"github.com/ipfs/go-ipfs/repo/fsrepo"
)

var FileStoreCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Interact with filestore objects",
	},
	Subcommands: map[string]*cmds.Command{
		"ls":       lsFileStore,
		"verify":   verifyFileStore,
		"rm":       rmFilestoreObjs,
		"clean":    cleanFileStore,
		"fix-pins":           repairPins,
		"repin":              repinFilestore,
	},
}

var lsFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "List objects in filestore",
		ShortDescription: `
List objects in the filestore.  If --quiet is specified only the
hashes are printed, otherwise the fields are as follows:
  <hash> <type> <filepath> <offset> <size> [<modtime>]
where <type> is one of"
  leaf: to indicate a leaf node where the contents are stored
        to in the file itself
  root: to indicate a root node that represents the whole file
  other: some other kind of node that represent part of a file
  invld: a leaf node that has been found invalid
and <filepath> is the part of the file the object represents.  The
part represented starts at <offset> and continues for <size> bytes.
If <offset> is the special value "-" than the "leaf" or "root" node
represents the whole file.
`,
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Write just hashes of objects."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		_, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		ch, _ := fsutil.List(fs, quiet)
		res.SetOutput(&chanWriter{ch, "", 0, false})
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

type chanWriter struct {
	ch     <-chan fsutil.ListRes
	buf    string
	offset int
	errors bool
}

func (w *chanWriter) Read(p []byte) (int, error) {
	if w.offset >= len(w.buf) {
		w.offset = 0
		res, more := <-w.ch
		if !more && !w.errors {
			return 0, io.EOF
		} else if !more && w.errors {
			return 0, errors.New("Some checks failed.")
		} else if fsutil.AnError(res.Status) {
			w.errors = true
		}
		w.buf = res.Format()
	}
	sz := copy(p, w.buf[w.offset:])
	w.offset += sz
	return sz, nil
}

var verifyFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Verify objects in filestore",
		ShortDescription: `
Verify nodes in the filestore.  The output is:
  <status> [<type> <filepath> <offset> <size> [<modtime>]]
where <type>, <filepath>, <offset>, <size> and <modtime> are the same
as in the "ls".  <status> is one of
  ok:      If the original data can be reconstructed
  complete: If all the blocks in the tree exists but no attempt was
            made to reconstruct the original data

  incomplete: Some of the blocks of the tree could not be read

  changed: If the leaf node is invalid because the contents of the file
           have changed
  no-file: If the file can not be found
  error:   If the file can be found but could not be read or some
           other error

  ERROR:   The block could not be read due to an internal error

  found:   The child of another node was found outside the filestore
  missing: The child of another node does not exist
  <blank>: The child of another node node exists but no attempt was
           made to verify it

  appended: The node is still valid but the original file was appended

  orphan: This node is a child of another node that was not found in
          the filestore

If --basic is specified then just scan leaf nodes to verify that they
are still valid.  Otherwise attempt to reconstruct the contents of of
all nodes and also check for orphan nodes (unless --skip-orphans is
also specified).

The --level option specifies how thorough the checks should be.  A
current meaning of the levels are:
  7-9: always check the contents
  2-6: check the contents if the modification time differs
  0-1: only check for the existence of blocks without verifying the
       contents of leaf nodes

The --verbose option specifies what to output.  The current values are:
  7-9: show everything
  5-6: don't show child nodes with a status of: ok, <blank>, or complete
  3-4: don't show child nodes
  0-2: don't child nodes and don't show root nodes with of: ok or complete
`,
	},
	Options: []cmds.Option{
		cmds.BoolOption("basic", "Perform a basic scan of leaf nodes only."),
		cmds.IntOption("level", "l", "0-9, Verification level.").Default(6),
		cmds.IntOption("verbose", "v", "0-9 Verbose level.").Default(6),
		cmds.BoolOption("skip-orphans", "Skip check for orphans."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		basic, _, err := res.Request().Option("basic").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		level, _, err := res.Request().Option("level").Int()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		verbose, _, err := res.Request().Option("verbose").Int()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		if level < 0 || level > 9 {
			res.SetError(errors.New("level must be between 0-9"), cmds.ErrNormal)
			return
		}
		skipOrphans, _, err := res.Request().Option("skip-orphans").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		if basic {
			ch, _ := fsutil.VerifyBasic(fs, level, verbose)
			res.SetOutput(&chanWriter{ch, "", 0, false})
		} else {
			ch, _ := fsutil.VerifyFull(node, fs, level, verbose, skipOrphans)
			res.SetOutput(&chanWriter{ch, "", 0, false})
		}
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var cleanFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Remove invalid or orphan nodes from the filestore.",
		ShortDescription: `
Removes invalid or orphan nodes from the filestore as specified by
<what>.  <what> is the status of a node reported by "verify", it can
be any of "changed", "no-file", "error", "incomplete", or "orphan".
"invalid" is an alias for "changed" and "no-file".  "full" is an alias
for "invalid" "incomplete" and "orphan" (basically remove everything
but "error").

It does the removal in three passes.  If there is nothing specified to
be removed in a pass that pass is skipped.  The first pass does a
"verify --basic" and is used to remove any "changed", "no-file" or "error"
leaf nodes.  The second pass does a "verify --level 0 --skip-orphans"
and will is used to remove any "incomplete" nodes due to missing children (the
"--level 0" only checks for the existence of leaf nodes, but does not
try to read the content).  The final pass will do a "verify --level 0"
and is used to remove any "orphan" nodes.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("what", true, true, "any of: changed no-file error incomplete orphan invalid full").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Produce less output."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		//_ = node
		//ch, err := fsutil.List(fs, quiet)
		rdr, err := fsutil.Clean(req, node, fs, quiet, req.Arguments()...)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		res.SetOutput(rdr)
		//res.SetOutput(&chanWriter{ch, "", 0, false})
		return
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var rmFilestoreObjs = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Remove objects from the filestore",
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("hash", true, true, "Multi-hashes to remove."),
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Produce less output."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		_ = fs
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		hashes := req.Arguments()
		rdr, wtr := io.Pipe()
		var rmWtr io.Writer = wtr
		if quiet {
			rmWtr = ioutil.Discard
		}
		go func() {
			numErrors := 0
			for _, mhash := range hashes {
				key := k.B58KeyDecode(mhash)
				err = fsutil.Delete(req, rmWtr, node, fs, key)
				if err != nil {
					fmt.Fprintf(wtr, "Error deleting %s: %s\n", mhash, err.Error())
					numErrors += 1
				}
			}
			if numErrors > 0 {
				wtr.CloseWithError(errors.New("Could not delete some keys."))
				return
			}
			wtr.Close()
		}()
		res.SetOutput(rdr)
		return
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

func extractFilestore(req cmds.Request) (node *core.IpfsNode, fs *filestore.Datastore, err error) {
	node, err = req.InvocContext().GetNode()
	if err != nil {
		return
	}
	repo, ok := node.Repo.Self().(*fsrepo.FSRepo)
	if !ok {
		err = errors.New("Not a FSRepo")
		return
	}
	fs = repo.Filestore()
	return
}

var repairPins = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Repair pins to non-existent or incomplete objects",
	},
	Options: []cmds.Option{
		cmds.BoolOption("dry-run", "n", "Report on what will be done."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			return
		}
		dryRun, _, err := res.Request().Option("dry-run").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			fsutil.RepairPins(node, fs, w, dryRun)
		}()
		res.SetOutput(r)
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var repinFilestore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Repin whole-file objects in filestore.",
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			return
		}
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			fsutil.Repin(req.Context(), node, fs, w)
		}()
		res.SetOutput(r)
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}
<commit_msg>Tweak help text for filestore commands.<commit_after>package commands

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"

	//ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
	//bs "github.com/ipfs/go-ipfs/blocks/blockstore"
	k "github.com/ipfs/go-ipfs/blocks/key"
	cmds "github.com/ipfs/go-ipfs/commands"
	"github.com/ipfs/go-ipfs/core"
	"github.com/ipfs/go-ipfs/filestore"
	fsutil "github.com/ipfs/go-ipfs/filestore/util"
	"github.com/ipfs/go-ipfs/repo/fsrepo"
)

var FileStoreCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Interact with filestore objects",
	},
	Subcommands: map[string]*cmds.Command{
		"ls":       lsFileStore,
		"verify":   verifyFileStore,
		"rm":       rmFilestoreObjs,
		"clean":    cleanFileStore,
		"fix-pins":           repairPins,
		"repin":              repinFilestore,
	},
}

var lsFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "List objects in filestore",
		ShortDescription: `
List objects in the filestore.  If --quiet is specified only the
hashes are printed, otherwise the fields are as follows:
  <hash> <type> <filepath> <offset> <size> [<modtime>]
where <type> is one of"
  leaf: to indicate a node where the contents are stored
        to in the file itself
  root: to indicate a root node that represents the whole file
  other: some other kind of node that represent part of a file
  invld: a leaf node that has been found invalid
and <filepath> is the part of the file the object represents.  The
part represented starts at <offset> and continues for <size> bytes.
If <offset> is the special value "-" than the "leaf" or "root" node
represents the whole file.
`,
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Write just hashes of objects."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		_, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		ch, _ := fsutil.List(fs, quiet)
		res.SetOutput(&chanWriter{ch, "", 0, false})
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

type chanWriter struct {
	ch     <-chan fsutil.ListRes
	buf    string
	offset int
	errors bool
}

func (w *chanWriter) Read(p []byte) (int, error) {
	if w.offset >= len(w.buf) {
		w.offset = 0
		res, more := <-w.ch
		if !more && !w.errors {
			return 0, io.EOF
		} else if !more && w.errors {
			return 0, errors.New("Some checks failed.")
		} else if fsutil.AnError(res.Status) {
			w.errors = true
		}
		w.buf = res.Format()
	}
	sz := copy(p, w.buf[w.offset:])
	w.offset += sz
	return sz, nil
}

var verifyFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Verify objects in filestore",
		ShortDescription: `
Verify nodes in the filestore.  The output is:
  <status> [<type> <filepath> <offset> <size> [<modtime>]]
where <type>, <filepath>, <offset>, <size> and <modtime> are the same
as in the "ls" command and <status> is one of

  ok:       the original data can be reconstructed
  complete: all the blocks in the tree exists but no attempt was
            made to reconstruct the original data

  incomplete: some of the blocks of the tree could not be read

  changed: the contents of the backing file have changed
  no-file: the backing file can not be found
  error:   the backing file can be found but could not be read

  ERROR:   the block could not be read due to an internal error

  found:   the child of another node was found outside the filestore
  missing: the child of another node does not exist
  <blank>: the child of another node node exists but no attempt was
           made to verify it

  appended: the node is still valid but the original file was appended

  orphan: the node is a child of another node that was not found in
          the filestore

If --basic is specified then just scan leaf nodes to verify that they
are still valid.  Otherwise attempt to reconstruct the contents of of
all nodes and also check for orphan nodes (unless --skip-orphans is
also specified).

The --level option specifies how thorough the checks should be.  A
current meaning of the levels are:
  7-9: always check the contents
  2-6: check the contents if the modification time differs
  0-1: only check for the existence of blocks without verifying the
       contents of leaf nodes

The --verbose option specifies what to output.  The current values are:
  7-9: show everything
  5-6: don't show child nodes with a status of: ok, <blank>, or complete
  3-4: don't show child nodes
  0-2: don't child nodes and don't show root nodes with of: ok or complete
`,
	},
	Options: []cmds.Option{
		cmds.BoolOption("basic", "Perform a basic scan of leaf nodes only."),
		cmds.IntOption("level", "l", "0-9, Verification level.").Default(6),
		cmds.IntOption("verbose", "v", "0-9 Verbose level.").Default(6),
		cmds.BoolOption("skip-orphans", "Skip check for orphans."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		basic, _, err := res.Request().Option("basic").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		level, _, err := res.Request().Option("level").Int()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		verbose, _, err := res.Request().Option("verbose").Int()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		if level < 0 || level > 9 {
			res.SetError(errors.New("level must be between 0-9"), cmds.ErrNormal)
			return
		}
		skipOrphans, _, err := res.Request().Option("skip-orphans").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		if basic {
			ch, _ := fsutil.VerifyBasic(fs, level, verbose)
			res.SetOutput(&chanWriter{ch, "", 0, false})
		} else {
			ch, _ := fsutil.VerifyFull(node, fs, level, verbose, skipOrphans)
			res.SetOutput(&chanWriter{ch, "", 0, false})
		}
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var cleanFileStore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Remove invalid or orphan nodes from the filestore.",
		ShortDescription: `
Removes invalid or orphan nodes from the filestore as specified by
<what>.  <what> is the status of a node as reported by "verify", it
can be any of "changed", "no-file", "error", "incomplete",
"orphan", "invalid" or "full".  "invalid" is an alias for "changed"
and "no-file" and "full" is an alias for "invalid" "incomplete" and
"orphan" (basically remove everything but "error").

It does the removal in three passes.  If there is nothing specified to
be removed in a pass that pass is skipped.  The first pass does a
"verify --basic" and is used to remove any "changed", "no-file" or
"error" nodes.  The second pass does a "verify --level 0
--skip-orphans" and will is used to remove any "incomplete" nodes due
to missing children (the "--level 0" only checks for the existence of
leaf nodes, but does not try to read the content).  The final pass
will do a "verify --level 0" and is used to remove any "orphan" nodes.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("what", true, true, "any of: changed no-file error incomplete orphan invalid full").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Produce less output."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		//_ = node
		//ch, err := fsutil.List(fs, quiet)
		rdr, err := fsutil.Clean(req, node, fs, quiet, req.Arguments()...)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		res.SetOutput(rdr)
		//res.SetOutput(&chanWriter{ch, "", 0, false})
		return
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var rmFilestoreObjs = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Remove objects from the filestore",
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("hash", true, true, "Multi-hashes to remove."),
	},
	Options: []cmds.Option{
		cmds.BoolOption("quiet", "q", "Produce less output."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		_ = fs
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		quiet, _, err := res.Request().Option("quiet").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		hashes := req.Arguments()
		rdr, wtr := io.Pipe()
		var rmWtr io.Writer = wtr
		if quiet {
			rmWtr = ioutil.Discard
		}
		go func() {
			numErrors := 0
			for _, mhash := range hashes {
				key := k.B58KeyDecode(mhash)
				err = fsutil.Delete(req, rmWtr, node, fs, key)
				if err != nil {
					fmt.Fprintf(wtr, "Error deleting %s: %s\n", mhash, err.Error())
					numErrors += 1
				}
			}
			if numErrors > 0 {
				wtr.CloseWithError(errors.New("Could not delete some keys."))
				return
			}
			wtr.Close()
		}()
		res.SetOutput(rdr)
		return
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

func extractFilestore(req cmds.Request) (node *core.IpfsNode, fs *filestore.Datastore, err error) {
	node, err = req.InvocContext().GetNode()
	if err != nil {
		return
	}
	repo, ok := node.Repo.Self().(*fsrepo.FSRepo)
	if !ok {
		err = errors.New("Not a FSRepo")
		return
	}
	fs = repo.Filestore()
	return
}

var repairPins = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Repair pins to non-existent or incomplete objects",
	},
	Options: []cmds.Option{
		cmds.BoolOption("dry-run", "n", "Report on what will be done."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			return
		}
		dryRun, _, err := res.Request().Option("dry-run").Bool()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			fsutil.RepairPins(node, fs, w, dryRun)
		}()
		res.SetOutput(r)
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}

var repinFilestore = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Repin whole-file objects in filestore.",
	},
	Run: func(req cmds.Request, res cmds.Response) {
		node, fs, err := extractFilestore(req)
		if err != nil {
			return
		}
		r, w := io.Pipe()
		go func() {
			defer w.Close()
			fsutil.Repin(req.Context(), node, fs, w)
		}()
		res.SetOutput(r)
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			return res.(io.Reader), nil
		},
	},
}
<|endoftext|>