diff options
Diffstat (limited to 'vendor/github.com/slack-go/slack/block_conv.go')
-rw-r--r-- | vendor/github.com/slack-go/slack/block_conv.go | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/vendor/github.com/slack-go/slack/block_conv.go b/vendor/github.com/slack-go/slack/block_conv.go new file mode 100644 index 00000000..ce48ce19 --- /dev/null +++ b/vendor/github.com/slack-go/slack/block_conv.go @@ -0,0 +1,353 @@ +package slack + +import ( + "encoding/json" + + "github.com/pkg/errors" +) + +type sumtype struct { + TypeVal string `json:"type"` +} + +// MarshalJSON implements the Marshaller interface for Blocks so that any JSON +// marshalling is delegated and proper type determination can be made before marshal +func (b Blocks) MarshalJSON() ([]byte, error) { + bytes, err := json.Marshal(b.BlockSet) + if err != nil { + return nil, err + } + + return bytes, nil +} + +// UnmarshalJSON implements the Unmarshaller interface for Blocks, so that any JSON +// unmarshalling is delegated and proper type determination can be made before unmarshal +func (b *Blocks) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + + if string(data) == "{}" { + return nil + } + + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + var blocks Blocks + for _, r := range raw { + s := sumtype{} + err := json.Unmarshal(r, &s) + if err != nil { + return err + } + + var blockType string + if s.TypeVal != "" { + blockType = s.TypeVal + } + + var block Block + switch blockType { + case "actions": + block = &ActionBlock{} + case "context": + block = &ContextBlock{} + case "divider": + block = &DividerBlock{} + case "image": + block = &ImageBlock{} + case "input": + block = &InputBlock{} + case "section": + block = &SectionBlock{} + case "rich_text": + // for now ignore the (complex) content of rich_text blocks until we can fully support it + continue + case "file": + // for now ignore the file blocks until we can fully support it + continue + default: + return errors.New("unsupported block type") + } + + err = json.Unmarshal(r, block) + if err != nil { + return err + } + + blocks.BlockSet = append(blocks.BlockSet, block) + } + + *b = blocks + return nil +} + +// UnmarshalJSON implements the Unmarshaller interface for InputBlock, so that any JSON +// unmarshalling is delegated and proper type determination can be made before unmarshal +func (b *InputBlock) UnmarshalJSON(data []byte) error { + type alias InputBlock + a := struct { + Element json.RawMessage `json:"element"` + *alias + }{ + alias: (*alias)(b), + } + + if err := json.Unmarshal(data, &a); err != nil { + return err + } + + s := sumtype{} + if err := json.Unmarshal(a.Element, &s); err != nil { + return nil + } + + var e BlockElement + switch s.TypeVal { + case "datepicker": + e = &DatePickerBlockElement{} + case "plain_text_input": + e = &PlainTextInputBlockElement{} + case "static_select", "external_select", "users_select", "conversations_select", "channels_select": + e = &SelectBlockElement{} + default: + return errors.New("unsupported block element type") + } + + if err := json.Unmarshal(a.Element, e); err != nil { + return err + } + b.Element = e + + return nil +} + +// MarshalJSON implements the Marshaller interface for BlockElements so that any JSON +// marshalling is delegated and proper type determination can be made before marshal +func (b *BlockElements) MarshalJSON() ([]byte, error) { + bytes, err := json.Marshal(b.ElementSet) + if err != nil { + return nil, err + } + + return bytes, nil +} + +// UnmarshalJSON implements the Unmarshaller interface for BlockElements, so that any JSON +// unmarshalling is delegated and proper type determination can be made before unmarshal +func (b *BlockElements) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + + if string(data) == "{}" { + return nil + } + + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + var blockElements BlockElements + for _, r := range raw { + s := sumtype{} + err := json.Unmarshal(r, &s) + if err != nil { + return err + } + + var blockElementType string + if s.TypeVal != "" { + blockElementType = s.TypeVal + } + + var blockElement BlockElement + switch blockElementType { + case "image": + blockElement = &ImageBlockElement{} + case "button": + blockElement = &ButtonBlockElement{} + case "overflow": + blockElement = &OverflowBlockElement{} + case "datepicker": + blockElement = &DatePickerBlockElement{} + case "plain_text_input": + blockElement = &PlainTextInputBlockElement{} + case "static_select", "external_select", "users_select", "conversations_select", "channels_select": + blockElement = &SelectBlockElement{} + default: + return errors.New("unsupported block element type") + } + + err = json.Unmarshal(r, blockElement) + if err != nil { + return err + } + + blockElements.ElementSet = append(blockElements.ElementSet, blockElement) + } + + *b = blockElements + return nil +} + +// MarshalJSON implements the Marshaller interface for Accessory so that any JSON +// marshalling is delegated and proper type determination can be made before marshal +func (a *Accessory) MarshalJSON() ([]byte, error) { + bytes, err := json.Marshal(toBlockElement(a)) + if err != nil { + return nil, err + } + + return bytes, nil +} + +// UnmarshalJSON implements the Unmarshaller interface for Accessory, so that any JSON +// unmarshalling is delegated and proper type determination can be made before unmarshal +func (a *Accessory) UnmarshalJSON(data []byte) error { + var r json.RawMessage + + if string(data) == "{\"accessory\":null}" { + return nil + } + + err := json.Unmarshal(data, &r) + if err != nil { + return err + } + + s := sumtype{} + err = json.Unmarshal(r, &s) + if err != nil { + return err + } + + var blockElementType string + if s.TypeVal != "" { + blockElementType = s.TypeVal + } + + switch blockElementType { + case "image": + element, err := unmarshalBlockElement(r, &ImageBlockElement{}) + if err != nil { + return err + } + a.ImageElement = element.(*ImageBlockElement) + case "button": + element, err := unmarshalBlockElement(r, &ButtonBlockElement{}) + if err != nil { + return err + } + a.ButtonElement = element.(*ButtonBlockElement) + case "overflow": + element, err := unmarshalBlockElement(r, &OverflowBlockElement{}) + if err != nil { + return err + } + a.OverflowElement = element.(*OverflowBlockElement) + case "datepicker": + element, err := unmarshalBlockElement(r, &DatePickerBlockElement{}) + if err != nil { + return err + } + a.DatePickerElement = element.(*DatePickerBlockElement) + case "static_select": + element, err := unmarshalBlockElement(r, &SelectBlockElement{}) + if err != nil { + return err + } + a.SelectElement = element.(*SelectBlockElement) + } + + return nil +} + +func unmarshalBlockElement(r json.RawMessage, element BlockElement) (BlockElement, error) { + err := json.Unmarshal(r, element) + if err != nil { + return nil, err + } + return element, nil +} + +func toBlockElement(element *Accessory) BlockElement { + if element.ImageElement != nil { + return element.ImageElement + } + if element.ButtonElement != nil { + return element.ButtonElement + } + if element.OverflowElement != nil { + return element.OverflowElement + } + if element.DatePickerElement != nil { + return element.DatePickerElement + } + if element.SelectElement != nil { + return element.SelectElement + } + + return nil +} + +// MarshalJSON implements the Marshaller interface for ContextElements so that any JSON +// marshalling is delegated and proper type determination can be made before marshal +func (e *ContextElements) MarshalJSON() ([]byte, error) { + bytes, err := json.Marshal(e.Elements) + if err != nil { + return nil, err + } + + return bytes, nil +} + +// UnmarshalJSON implements the Unmarshaller interface for ContextElements, so that any JSON +// unmarshalling is delegated and proper type determination can be made before unmarshal +func (e *ContextElements) UnmarshalJSON(data []byte) error { + var raw []json.RawMessage + + if string(data) == "{\"elements\":null}" { + return nil + } + + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + for _, r := range raw { + s := sumtype{} + err := json.Unmarshal(r, &s) + if err != nil { + return err + } + + var contextElementType string + if s.TypeVal != "" { + contextElementType = s.TypeVal + } + + switch contextElementType { + case PlainTextType, MarkdownType: + elem, err := unmarshalBlockObject(r, &TextBlockObject{}) + if err != nil { + return err + } + + e.Elements = append(e.Elements, elem.(*TextBlockObject)) + case "image": + elem, err := unmarshalBlockElement(r, &ImageBlockElement{}) + if err != nil { + return err + } + + e.Elements = append(e.Elements, elem.(*ImageBlockElement)) + default: + return errors.New("unsupported context element type") + } + } + + return nil +} |