// Package store implements a synchronous in-memory K/V store // fronted by an HTTP server. package store import ( "io" "net/http" "sync" ) type Map struct { m sync.Map } func New(from map[string]string) *Map { var m Map for k, v := range from { m.Set(k, v) } return &m } func (m *Map) Get(k string) (string, bool) { r, ok := m.m.Load(k) return r.(string), ok } func (m *Map) Set(k, v string) { m.m.Store(k, v) } func (m *Map) Delete(k string) { m.m.Delete(k) } func (m *Map) Router() http.Handler { r := http.NewServeMux() r.HandleFunc("GET /{key}", m.get) r.HandleFunc("PUT /{key}", m.set) r.HandleFunc("POST /{key}", m.set) r.HandleFunc("DELETE /{key}", m.delete) return r } func (m *Map) get(w http.ResponseWriter, r *http.Request) { k := r.PathValue("key") v, ok := m.Get(k) if !ok { http.Error(w, "not found", http.StatusNotFound) } io.WriteString(w, v) } func (m *Map) set(w http.ResponseWriter, r *http.Request) { k := r.PathValue("key") b, err := io.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) } m.Set(k, string(b)) w.WriteHeader(http.StatusNoContent) } func (m *Map) delete(w http.ResponseWriter, r *http.Request) { k := r.PathValue("key") m.Delete(k) w.WriteHeader(http.StatusNoContent) }