1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 11:46:16 +00:00
mycorrhiza/hyphae/interface.go

105 lines
2.2 KiB
Go
Raw Normal View History

2022-02-03 21:26:08 +00:00
package hyphae
2022-02-04 11:14:53 +00:00
import (
"regexp"
"strings"
"sync"
)
// HyphaPattern is a pattern which all hyphae names must match.
var HyphaPattern = regexp.MustCompile(`[^?!:#@><*|"'&%{}]+`)
// IsValidName checks for invalid characters and path traversals.
func IsValidName(hyphaName string) bool {
if !HyphaPattern.MatchString(hyphaName) {
return false
}
for _, segment := range strings.Split(hyphaName, "/") {
if segment == ".git" || segment == ".." {
return false
}
}
return true
}
2022-02-03 21:26:08 +00:00
type HyphaKind int
const (
HyphaEmpty HyphaKind = iota
HyphaText
HyphaMedia
)
2022-02-04 11:00:38 +00:00
// Hypher is a temporary name for this interface. The name will become MediaHypha, once the struct with the said name is deprecated for good.
2022-02-03 21:26:08 +00:00
type Hypher interface {
sync.Locker
CanonicalName() string
Kind() HyphaKind
DoesExist() bool
2022-02-03 21:26:08 +00:00
HasTextPart() bool
TextPartPath() string
}
// DeleteHypha deletes the hypha from the storage.
func DeleteHypha(h Hypher) {
byNamesMutex.Lock()
h.Lock()
delete(byNames, h.CanonicalName())
decrementCount()
byNamesMutex.Unlock()
h.Unlock()
}
// RenameHyphaTo renames a hypha and performs respective changes in the storage.
func RenameHyphaTo(h Hypher, newName string) {
byNamesMutex.Lock()
h.Lock()
delete(byNames, h.CanonicalName())
2022-02-04 11:00:38 +00:00
h.(*MediaHypha).SetName(newName)
byNames[h.CanonicalName()] = h.(*MediaHypha)
byNamesMutex.Unlock()
h.Unlock()
}
2022-02-04 11:14:53 +00:00
// insert inserts the hypha into the storage. A previous record is used if possible. Count incrementation is done if needed.
func insert(h Hypher) (madeNewRecord bool) {
hp, recorded := byNames[h.CanonicalName()]
if recorded {
hp.(*MediaHypha).mergeIn(h)
} else {
storeHypha(h)
incrementCount()
}
return !recorded
}
// InsertIfNew checks whether hypha exists and returns `true` if it didn't and has been created.
func InsertIfNew(h Hypher) (madeNewRecord bool) {
if h.DoesExist() {
return false
}
return insert(h)
}
func storeHypha(h Hypher) {
byNamesMutex.Lock()
byNames[h.CanonicalName()] = h
byNamesMutex.Unlock()
h.Lock()
h.(*MediaHypha).Exists = true
h.Unlock()
}
// ByName returns a hypha by name. It may have been recorded to the storage.
func ByName(hyphaName string) (h Hypher) {
h, recorded := byNames[hyphaName]
if recorded {
return h
}
return NewEmptyHypha(hyphaName)
}