Add method of entity.Address to generate a nickname

This commit is contained in:
Sasha Koshka 2024-02-13 19:10:24 -05:00
parent c89cbc24fe
commit d117e15157
1 changed files with 47 additions and 1 deletions

View File

@ -1,6 +1,9 @@
package entity
import "fmt"
import "strings"
import "unicode"
import "unicode/utf8"
import "path/filepath"
import "git.tebibyte.media/sashakoshka/fspl/errors"
@ -31,7 +34,7 @@ func (addr Address) String () string {
}
// SourceFile returns the FSPL source file associated with the address. If the
// address does not point to an FSPL source file, it returns "", false.
func (addr Address) IsSourceFile () (string, bool) {
func (addr Address) SourceFile () (string, bool) {
ext := filepath.Ext(string(addr))
if ext == ".fspl" {
return "", false
@ -52,3 +55,46 @@ func (addr Address) Module () (string, bool) {
return "", false
}
}
// Nickname automatically generates a nickname from the address, which is a
// valid Ident token. On failure "", false is returned. The nickname is
// generated according to the folowing rules:
//
// - If the name contains at least one dot, the last dot and everything after
// it is removed
// - All non-letter, non-numeric characters are removed, and any letters that
// were directly after them are converted to uppercase
// - All numeric digits at the start of the string are removed
// - The first character is converted to lowercase
func (addr Address) Nickname () (string, bool) {
// get the normalized basename with no extension
base := filepath.Base(string(addr))
base = strings.TrimSuffix(base, filepath.Ext(base))
// remove all non-letter, non-digit characters and convert to camel case
nickname := ""
uppercase := false
for _, char := range base {
if unicode.IsLetter(char) || unicode.IsDigit(char) {
if uppercase {
uppercase = false
char = unicode.ToUpper(char)
}
nickname += string(char)
} else {
uppercase = true
}
}
// remove numeric digits
for len(nickname) > 0 {
char, size := utf8.DecodeRuneInString(nickname)
nickname = nickname[size:]
if unicode.IsLetter(char) {
// lowercase the first letter
nickname = string(unicode.ToLower(char)) + nickname
break
}
}
return nickname, nickname != ""
}