89 lines
2.6 KiB
Go
89 lines
2.6 KiB
Go
package notice
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
func Text(content string) Message {
|
|
return Message{Type: MessageText, Content: content}
|
|
}
|
|
|
|
func ColorText(segments ...TextSegment) Message {
|
|
return Message{Type: MessageColorText, Segments: segments}
|
|
}
|
|
|
|
func Markdown(title, content string) Message {
|
|
return Message{Type: MessageMarkdown, Title: title, Content: content}
|
|
}
|
|
|
|
func Card(content CardContent) Message {
|
|
return Message{Type: MessageCard, Card: &content}
|
|
}
|
|
|
|
func validateMessage(message Message) error {
|
|
switch message.Type {
|
|
case MessageText:
|
|
if strings.TrimSpace(message.Content) == "" {
|
|
return fmt.Errorf("%w: text content is empty", ErrInvalidMessage)
|
|
}
|
|
case MessageMarkdown:
|
|
if strings.TrimSpace(message.Content) == "" {
|
|
return fmt.Errorf("%w: markdown content is empty", ErrInvalidMessage)
|
|
}
|
|
case MessageColorText:
|
|
nonEmpty := false
|
|
for _, segment := range message.Segments {
|
|
if strings.TrimSpace(segment.Text) != "" {
|
|
nonEmpty = true
|
|
}
|
|
if !validColor(segment.Color) {
|
|
return fmt.Errorf("%w: unsupported color %q", ErrInvalidMessage, segment.Color)
|
|
}
|
|
}
|
|
if !nonEmpty {
|
|
return fmt.Errorf("%w: color text segments are empty", ErrInvalidMessage)
|
|
}
|
|
case MessageCard:
|
|
if message.Card == nil {
|
|
return fmt.Errorf("%w: card content is nil", ErrInvalidMessage)
|
|
}
|
|
if strings.TrimSpace(message.Card.Title) == "" && strings.TrimSpace(message.Card.Markdown) == "" {
|
|
return fmt.Errorf("%w: card title and markdown are empty", ErrInvalidMessage)
|
|
}
|
|
if !validTheme(message.Card.Theme) {
|
|
return fmt.Errorf("%w: unsupported card theme %q", ErrInvalidMessage, message.Card.Theme)
|
|
}
|
|
for _, action := range message.Card.Actions {
|
|
parsed, err := url.ParseRequestURI(strings.TrimSpace(action.URL))
|
|
if strings.TrimSpace(action.Text) == "" || err != nil || parsed.Scheme != "https" || parsed.Host == "" {
|
|
return fmt.Errorf("%w: card action requires text and HTTPS URL", ErrInvalidMessage)
|
|
}
|
|
}
|
|
default:
|
|
return fmt.Errorf("%w: unsupported message type %q", ErrInvalidMessage, message.Type)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validColor(color Color) bool {
|
|
switch color {
|
|
case "", ColorDefault, ColorInfo, ColorSuccess, ColorWarning, ColorDanger, ColorMuted:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func validTheme(theme CardTheme) bool {
|
|
switch theme {
|
|
case "", CardThemeDefault, CardThemeBlue, CardThemeWathet, CardThemeTurquoise, CardThemeGreen,
|
|
CardThemeYellow, CardThemeOrange, CardThemeRed, CardThemeCarmine, CardThemeViolet,
|
|
CardThemePurple, CardThemeIndigo, CardThemeGrey:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|