diff --git a/internal/repository/mime/mime.go b/internal/repository/mime/mime.go new file mode 100644 index 0000000000..ef39897531 --- /dev/null +++ b/internal/repository/mime/mime.go @@ -0,0 +1,16 @@ +package mime + +import "strings" + +// Split spits the mimetype into its main type and subtype. +func Split(mimeTypeFull string) (mimeType, mimeSubType string) { + // Replace with strings.Cut() when Go 1.18 is our new base version. + separatorIndex := strings.IndexByte(mimeTypeFull, '/') + if separatorIndex == -1 || mimeTypeFull[separatorIndex+1:] == "" { + return "", "" // Empty or only one part. Ignore. + } + + mimeType = mimeTypeFull[:separatorIndex] + mimeSubType = mimeTypeFull[separatorIndex+1:] + return +} diff --git a/internal/repository/mime/mime_test.go b/internal/repository/mime/mime_test.go new file mode 100644 index 0000000000..5cedb2034a --- /dev/null +++ b/internal/repository/mime/mime_test.go @@ -0,0 +1,21 @@ +package mime + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSplitMimeType(t *testing.T) { + main, sub := Split("text/plain") + assert.Equal(t, "text", main) + assert.Equal(t, "plain", sub) + + main, sub = Split("text/") + assert.Empty(t, main) + assert.Empty(t, sub) + + main, sub = Split("") + assert.Empty(t, main) + assert.Empty(t, sub) +} diff --git a/storage/filter.go b/storage/filter.go index c6bec67c42..bcc9adac05 100644 --- a/storage/filter.go +++ b/storage/filter.go @@ -4,6 +4,7 @@ import ( "strings" "fyne.io/fyne/v2" + "fyne.io/fyne/v2/internal/repository/mime" ) // FileFilter is an interface that can be implemented to provide a filter to a file dialog. @@ -42,18 +43,21 @@ func NewExtensionFileFilter(extensions []string) FileFilter { // Matches returns true if a file URI has one of the filtered mimetypes. func (mt *MimeTypeFileFilter) Matches(uri fyne.URI) bool { - mimeType, mimeSubType := splitMimeType(uri) + mimeType, mimeSubType := mime.Split(uri.MimeType()) for _, mimeTypeFull := range mt.MimeTypes { - mimeTypeSplit := strings.Split(mimeTypeFull, "/") - if len(mimeTypeSplit) <= 1 { + mType, mSubType := mime.Split(mimeTypeFull) + if mType == "" || mSubType == "" { continue } - mType := mimeTypeSplit[0] - mSubType := strings.Split(mimeTypeSplit[1], ";")[0] - if mType == mimeType { - if mSubType == mimeSubType || mSubType == "*" { - return true - } + + // Replace with strings.Cut() when Go 1.18 is our new base version. + subTypeSeparatorIndex := strings.IndexByte(mSubType, ';') + if subTypeSeparatorIndex != -1 { + mSubType = mSubType[:subTypeSeparatorIndex] + } + + if mType == mimeType && (mSubType == mimeSubType || mSubType == "*") { + return true } } return false @@ -64,16 +68,3 @@ func (mt *MimeTypeFileFilter) Matches(uri fyne.URI) bool { func NewMimeTypeFileFilter(mimeTypes []string) FileFilter { return &MimeTypeFileFilter{MimeTypes: mimeTypes} } - -func splitMimeType(uri fyne.URI) (mimeType, mimeSubType string) { - mimeTypeFull := uri.MimeType() - mimeTypeSplit := strings.Split(mimeTypeFull, "/") - if len(mimeTypeSplit) <= 1 { - mimeType, mimeSubType = "", "" - return - } - mimeType = mimeTypeSplit[0] - mimeSubType = mimeTypeSplit[1] - - return -} diff --git a/storage/repository/uri.go b/storage/repository/uri.go index bb07544dfb..44a5416b19 100644 --- a/storage/repository/uri.go +++ b/storage/repository/uri.go @@ -30,7 +30,6 @@ func (u *uri) Name() string { } func (u *uri) MimeType() string { - mimeTypeFull := mime.TypeByExtension(u.Extension()) if mimeTypeFull == "" { mimeTypeFull = "text/plain" @@ -50,7 +49,12 @@ func (u *uri) MimeType() string { } } - return strings.Split(mimeTypeFull, ";")[0] + // Replace with strings.Cut() when Go 1.18 is our new base version. + semicolonIndex := strings.IndexByte(mimeTypeFull, ';') + if semicolonIndex == -1 { + return mimeTypeFull + } + return mimeTypeFull[:semicolonIndex] } func (u *uri) Scheme() string { diff --git a/widget/fileicon.go b/widget/fileicon.go index 60041e481a..0ea2ea1833 100644 --- a/widget/fileicon.go +++ b/widget/fileicon.go @@ -1,10 +1,9 @@ package widget import ( - "strings" - "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" + "fyne.io/fyne/v2/internal/repository/mime" "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/theme" @@ -99,7 +98,8 @@ func (i *FileIcon) lookupIcon(uri fyne.URI) fyne.Resource { return theme.FolderIcon() } - switch splitMimeType(uri) { + mainMimeType, _ := mime.Split(uri.MimeType()) + switch mainMimeType { case "application": return theme.FileApplicationIcon() case "audio": @@ -201,11 +201,3 @@ func trimmedExtension(uri fyne.URI) string { } return ext } - -func splitMimeType(uri fyne.URI) string { - mimeTypeSplit := strings.Split(uri.MimeType(), "/") - if len(mimeTypeSplit) <= 1 { - return "" - } - return mimeTypeSplit[0] -}