package domain import ( "fmt" "strings" ) type Tag struct { name string } func NewTag(name string) (*Tag, error) { if name == "" { return nil, fmt.Errorf("tag name cannot be empty") } if !strings.HasPrefix(name, "#") { name = "#" + name } if !isValidTagName(name) { return nil, ErrInvalidTag } return &Tag{name: name}, nil } func (t *Tag) Name() string { return t.name } func (t *Tag) Parent() *Tag { if !t.IsNested() { return nil } lastSlash := strings.LastIndex(t.name, "/") if lastSlash == -1 { return nil } parentName := t.name[:lastSlash] parent, _ := NewTag(parentName) return parent } func (t *Tag) IsNested() bool { return strings.Contains(t.name, "/") } func (t *Tag) String() string { return t.name } func isValidTagName(name string) bool { if !strings.HasPrefix(name, "#") { return false } if len(name) <= 1 { return false } tagContent := name[1:] if strings.Contains(tagContent, " ") { return false } if strings.HasPrefix(tagContent, "/") || strings.HasSuffix(tagContent, "/") { return false } if strings.Contains(tagContent, "//") { return false } return true }