osamingo/jsonrpc

View on GitHub
method.go

Summary

Maintainability
A
0 mins
Test Coverage
package jsonrpc

import (
    "errors"
    "sync"
)

type (
    // A MethodRepository has JSON-RPC method functions.
    MethodRepository struct {
        m sync.RWMutex
        r map[string]Metadata
    }
    // Metadata has method meta data.
    Metadata struct {
        Handler Handler
        Params  any
        Result  any
    }
)

// NewMethodRepository returns new MethodRepository.
func NewMethodRepository() *MethodRepository {
    return &MethodRepository{
        m: sync.RWMutex{},
        r: map[string]Metadata{},
    }
}

// TakeMethodMetadata takes metadata in MethodRepository for request.
func (mr *MethodRepository) TakeMethodMetadata(r *Request) (Metadata, *Error) {
    if r.Method == "" || r.Version != Version {
        return Metadata{}, ErrInvalidParams()
    }

    mr.m.RLock()
    md, ok := mr.r[r.Method]
    mr.m.RUnlock()
    if !ok {
        return Metadata{}, ErrMethodNotFound()
    }

    return md, nil
}

// TakeMethod takes jsonrpc.Func in MethodRepository.
func (mr *MethodRepository) TakeMethod(r *Request) (Handler, *Error) { //nolint: ireturn
    md, err := mr.TakeMethodMetadata(r)
    if err != nil {
        return nil, err
    }

    return md.Handler, nil
}

// RegisterMethod registers jsonrpc.Func to MethodRepository.
func (mr *MethodRepository) RegisterMethod(method string, h Handler, params, result any) error {
    if method == "" || h == nil {
        return errors.New("jsonrpc: method name and function should not be empty") //nolint: goerr113
    }
    mr.m.Lock()
    mr.r[method] = Metadata{
        Handler: h,
        Params:  params,
        Result:  result,
    }
    mr.m.Unlock()

    return nil
}

// Methods returns registered methods.
func (mr *MethodRepository) Methods() map[string]Metadata {
    mr.m.RLock()
    ml := make(map[string]Metadata, len(mr.r))
    for k, md := range mr.r {
        ml[k] = md
    }
    mr.m.RUnlock()

    return ml
}