diff --git a/cmd/main.go b/cmd/main.go index 24145c7..d2efd75 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,18 +3,19 @@ package main import ( "log/slog" "os" - "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" + "github.com/KristianJBorgwarth/dendrite.daemon/core/handlers" + "github.com/KristianJBorgwarth/dendrite.daemon/core/server" _ "modernc.org/sqlite" ) func main() { - server := rpc.NewServer() + server := server.NewServer() server.Register("initialize", handlers.InitializeHandler{}) - if err := server.Serve(os.Stdin, os.Stdout); err != nil { + if err := server.Run(os.Stdin, os.Stdout); err != nil { slog.Error("server error", "error", err) } } diff --git a/core/handlers/create_note.go b/core/handlers/create_note_handler.go similarity index 92% rename from core/handlers/create_note.go rename to core/handlers/create_note_handler.go index 8e3361b..151406d 100644 --- a/core/handlers/create_note.go +++ b/core/handlers/create_note_handler.go @@ -46,12 +46,12 @@ func (h CreateNoteHandler) Handle(ctx context.Context, params []byte) (*rpc.Resp return nil, h.ReturnError(err) } - err = h.tagRepo.Upsert(tags) + err = h.tagRepo.Upsert(ctx, tags) if err != nil { return nil, h.ReturnError(err) } - err = h.noteRepo.Upsert(cmd.Title, cmd.Path, frontmatter.Slugify(cmd.Title)) + err = h.noteRepo.Upsert(ctx, cmd.Title, cmd.Path, frontmatter.Slugify(cmd.Title)) if err != nil { return nil, h.ReturnError(err) } diff --git a/core/handlers/handler.go b/core/handlers/handler.go new file mode 100644 index 0000000..6ba51a2 --- /dev/null +++ b/core/handlers/handler.go @@ -0,0 +1,12 @@ +package handlers + +import ( + "context" + "encoding/json" + + "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" +) + +type Handler interface { + Handle(ctx context.Context, raw json.RawMessage) (any, *rpc.Error) +} diff --git a/core/handlers/initialize.go b/core/handlers/initialize_handler.go similarity index 85% rename from core/handlers/initialize.go rename to core/handlers/initialize_handler.go index c6cf01f..a84003d 100644 --- a/core/handlers/initialize.go +++ b/core/handlers/initialize_handler.go @@ -1,7 +1,9 @@ package handlers import ( + "context" "encoding/json" + "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" "github.com/KristianJBorgwarth/dendrite.daemon/persistence" ) @@ -12,7 +14,7 @@ type initializeCommand struct { type InitializeHandler struct{} -func (h InitializeHandler) Handle(raw json.RawMessage) (any, *rpc.Error) { +func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, *rpc.Error) { var params initializeCommand if err := json.Unmarshal(raw, ¶ms); err != nil { diff --git a/core/rpc/server.go b/core/rpc/server.go deleted file mode 100644 index 46ff838..0000000 --- a/core/rpc/server.go +++ /dev/null @@ -1,83 +0,0 @@ -package rpc - -import ( - "bufio" - "encoding/json" - "fmt" - "io" -) - -type Handler interface { - Handle(json.RawMessage) (any, *Error) -} - -type Server struct { - handlers map[string]Handler -} - -func NewServer() *Server { - return &Server{ - handlers: make(map[string]Handler), - } -} - -func (s *Server) Register(method string, handler Handler) { - s.handlers[method] = handler -} - -func (s *Server) Serve(r io.Reader, w io.Writer) error { - scanner := bufio.NewScanner(r) - - for scanner.Scan() { - line := scanner.Bytes() - var req Request - if err := json.Unmarshal(line, &req); err != nil { - s.write(w, Response{ - Jsonrpc: "2.0", - Error: &Error{Code: -32700, Message: "parse error"}, - }) - continue - } - - s.handle(w, req) - - } - - return scanner.Err() -} - -func (s *Server) handle(w io.Writer, req Request) { - handler, ok := s.handlers[req.Method] - - if !ok { - s.respond(w, req.ID, nil, &Error{ - Code: -32601, - Message: "method not found", - }) - return - } - - result, err := handler.Handle(req.Params) - - if req.ID == nil { - return - } - - s.respond(w, req.ID, result, err) -} - -func (s *Server) respond(w io.Writer, id *int, result any, err *Error) { - resp := Response{ - Jsonrpc: "2.0", - ID: id, - Result: result, - Error: err, - } - - s.write(w, resp) -} - -func (s *Server) write(w io.Writer, resp Response) { - data, _ := json.Marshal(resp) - fmt.Fprintln(w, string(data)) -} diff --git a/core/server/server.go b/core/server/server.go new file mode 100644 index 0000000..a9bf558 --- /dev/null +++ b/core/server/server.go @@ -0,0 +1,84 @@ +// Package server contains the server running the JSON-RPC 2.0 Protocol. +package server + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "github.com/KristianJBorgwarth/dendrite.daemon/core/handlers" + "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" +) + +type Server struct { + handlers map[string]handlers.Handler +} + +func NewServer() *Server { + return &Server{ + handlers: make(map[string]handlers.Handler), + } +} + +func (s *Server) Register(method string, handler handlers.Handler) { + s.handlers[method] = handler +} + +func (s *Server) Run(r io.Reader, w io.Writer) error { + scanner := bufio.NewScanner(r) + + for scanner.Scan() { + line := scanner.Bytes() + var req rpc.Request + if err := json.Unmarshal(line, &req); err != nil { + s.write(w, rpc.Response{ + Jsonrpc: "2.0", + Error: &rpc.Error{Code: -32700, Message: "parse error"}, + }) + continue + } + + s.handle(w, req) + + } + + return scanner.Err() +} + +func (s *Server) handle(w io.Writer, req rpc.Request) { + ctx := context.Background() + handler, ok := s.handlers[req.Method] + + if !ok { + s.respond(w, req.ID, nil, &rpc.Error{ + Code: -32601, + Message: "method not found", + }) + return +} + + result, err := handler.Handle(ctx, req.Params) + + if req.ID == nil { + return + } + + s.respond(w, req.ID, result, err) +} + +func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) { + resp := rpc.Response{ + Jsonrpc: "2.0", + ID: id, + Result: result, + Error: err, + } + + s.write(w, resp) +} + +func (s *Server) write(w io.Writer, resp rpc.Response) { + data, _ := json.Marshal(resp) + fmt.Fprintln(w, string(data)) +} diff --git a/core/services/note_service.go b/core/services/note_service.go deleted file mode 100644 index e69de29..0000000