- Add complete domain layer: Note, Vault, WikiLink, Tag, Frontmatter, Graph entities - Implement repository interfaces for data access abstraction - Create comprehensive configuration system with YAML and env support - Add CLI entry point with signal handling and graceful shutdown - Fix mermaid diagram syntax in design.md (array notation) - Add CLAUDE.md for development guidance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
package domain
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
type Frontmatter struct {
|
|
data map[string]interface{}
|
|
}
|
|
|
|
func NewFrontmatter() *Frontmatter {
|
|
return &Frontmatter{
|
|
data: make(map[string]interface{}),
|
|
}
|
|
}
|
|
|
|
func NewFrontmatterFromMap(data map[string]interface{}) *Frontmatter {
|
|
fm := NewFrontmatter()
|
|
for k, v := range data {
|
|
fm.data[k] = v
|
|
}
|
|
return fm
|
|
}
|
|
|
|
func (f *Frontmatter) Get(key string) interface{} {
|
|
return f.data[key]
|
|
}
|
|
|
|
func (f *Frontmatter) Set(key string, value interface{}) error {
|
|
if key == "" {
|
|
return fmt.Errorf("frontmatter key cannot be empty")
|
|
}
|
|
f.data[key] = value
|
|
return nil
|
|
}
|
|
|
|
func (f *Frontmatter) Has(key string) bool {
|
|
_, exists := f.data[key]
|
|
return exists
|
|
}
|
|
|
|
func (f *Frontmatter) Delete(key string) {
|
|
delete(f.data, key)
|
|
}
|
|
|
|
func (f *Frontmatter) Keys() []string {
|
|
keys := make([]string, 0, len(f.data))
|
|
for k := range f.data {
|
|
keys = append(keys, k)
|
|
}
|
|
return keys
|
|
}
|
|
|
|
func (f *Frontmatter) Data() map[string]interface{} {
|
|
result := make(map[string]interface{})
|
|
for k, v := range f.data {
|
|
result[k] = v
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (f *Frontmatter) IsEmpty() bool {
|
|
return len(f.data) == 0
|
|
}
|
|
|
|
func (f *Frontmatter) Merge(other *Frontmatter) *Frontmatter {
|
|
merged := NewFrontmatter()
|
|
|
|
for k, v := range f.data {
|
|
merged.data[k] = v
|
|
}
|
|
|
|
for k, v := range other.data {
|
|
merged.data[k] = v
|
|
}
|
|
|
|
return merged
|
|
}
|
|
|
|
func (f *Frontmatter) Clone() *Frontmatter {
|
|
cloned := NewFrontmatter()
|
|
for k, v := range f.data {
|
|
cloned.data[k] = deepCopy(v)
|
|
}
|
|
return cloned
|
|
}
|
|
|
|
func deepCopy(src interface{}) interface{} {
|
|
if src == nil {
|
|
return nil
|
|
}
|
|
|
|
switch v := src.(type) {
|
|
case map[string]interface{}:
|
|
dst := make(map[string]interface{})
|
|
for key, val := range v {
|
|
dst[key] = deepCopy(val)
|
|
}
|
|
return dst
|
|
case []interface{}:
|
|
dst := make([]interface{}, len(v))
|
|
for i, val := range v {
|
|
dst[i] = deepCopy(val)
|
|
}
|
|
return dst
|
|
default:
|
|
return v
|
|
}
|
|
} |