package registry import ( "bufio" "encoding/json" "errors" "os" "time" ) var ( ErrNotFound = errors.New("entry not found") ErrKeyExists = errors.New("key already exists") ErrInvalidEntry = errors.New("invalid entry") ) type Registry struct { path string entries map[string]*Entry } func Load(path string) (*Registry, error) { r := &Registry{ path: path, entries: make(map[string]*Entry), } file, err := os.Open(path) if err != nil { if os.IsNotExist(err) { return r, nil } return nil, err } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() if line == "" { continue } var entry Entry if err := json.Unmarshal([]byte(line), &entry); err != nil { continue } r.entries[entry.Key] = &entry } if err := scanner.Err(); err != nil { return nil, err } return r, nil } func (r *Registry) Save() error { file, err := os.Create(r.path) if err != nil { return err } defer file.Close() for _, entry := range r.entries { data, err := json.Marshal(entry) if err != nil { return err } if _, err := file.Write(data); err != nil { return err } if _, err := file.WriteString("\n"); err != nil { return err } } return nil } func (r *Registry) Add(entry *Entry) error { if entry.Key == "" { return ErrInvalidEntry } if _, exists := r.entries[entry.Key]; exists { return ErrKeyExists } now := time.Now() entry.CreatedAt = now entry.UpdatedAt = now r.entries[entry.Key] = entry return r.Save() } func (r *Registry) Get(key string) (*Entry, error) { entry, exists := r.entries[key] if !exists { return nil, ErrNotFound } return entry, nil } func (r *Registry) Update(entry *Entry) error { if _, exists := r.entries[entry.Key]; !exists { return ErrNotFound } entry.UpdatedAt = time.Now() r.entries[entry.Key] = entry return r.Save() } func (r *Registry) Remove(key string) error { if _, exists := r.entries[key]; !exists { return ErrNotFound } delete(r.entries, key) return r.Save() } func (r *Registry) List() []*Entry { entries := make([]*Entry, 0, len(r.entries)) for _, entry := range r.entries { entries = append(entries, entry) } return entries } func (r *Registry) Exists(key string) bool { _, exists := r.entries[key] return exists }